Compare commits

...

20 Commits
1.0.0 ... main

Author SHA1 Message Date
Omar Polo 5ac1e2631b Don't need to copy strings around and hardcode the max table len from pf
internals, just assign a pointer (eventually from argv.)

while here also add a usage() function and error if more than one
argument are passed.
2022-09-24 19:40:39 +02:00
solene 550cfca6d1 Merge pull request 'fix_readme_path' (#4) from prx/iblock:fix_readme_path into main
Reviewed-on: #4
2022-09-18 13:19:04 +00:00
Solene Rapenne f6e72657a5 Makefile: allow override of PREFIX 2022-09-18 15:15:24 +02:00
prx b95e736dc7 add fork check for error and reformat 2022-09-18 14:43:53 +02:00
prx a2702bad84 fix PREFIX in readme 2022-09-18 14:31:03 +02:00
solene 747a833df3 Merge pull request 'iblock: kill established connections after the ban' (#3) from fork into main
Reviewed-on: #3
2022-09-17 15:25:57 +00:00
Solene Rapenne 1f21555152 iblock: kill established connections after the ban 2022-09-17 16:52:03 +02:00
solene f272f53c0c Merge pull request 'actually use cflags' (#2) from prx/iblock:main into main
Reviewed-on: #2
2022-08-30 07:26:22 +00:00
prx 7910b7ea11 actually use cflags 2022-08-25 10:04:53 +02:00
solene 1a60f738f2 Merge pull request 'main' (#1) from prx/iblock:main into main
Reviewed-on: #1
2022-08-22 14:02:23 +00:00
prx ff5ff21ca5 make install is set 2022-08-22 15:05:26 +02:00
prx 8fe70f68e8 make sure PREFIX is set 2022-08-22 15:04:26 +02:00
prx 3cadbbe7df no need to look in PATH 2022-08-22 15:02:17 +02:00
prx 9b755ab627 typo 2022-08-22 14:56:35 +02:00
prx 28eb2bfbeb if and switch aren't functions 2022-08-22 14:56:21 +02:00
prx 7c1edb0feb remove useless {} 2022-08-22 14:55:45 +02:00
prx 2b226c9a02 initialize variables, use strlcpy return value 2022-08-22 14:55:25 +02:00
prx f9d12c9ef5 avoid colision with common table names 2022-08-22 14:50:40 +02:00
prx 7f474df2ee set TABLE_LEN according to pf source 2022-08-22 14:50:27 +02:00
Solene Rapenne ee7a713fc9 add installation target to makefile 2022-08-18 10:57:50 +02:00
3 changed files with 77 additions and 35 deletions

View File

@ -1,15 +1,22 @@
CFLAGS += -pedantic -Wall -Wextra -Wmissing-prototypes \
-Werror -Wshadow -Wstrict-overflow -fno-strict-aliasing \
-Wstrict-prototypes -Wwrite-strings \
-Os
PREFIX = /usr/local
CFLAGS = -pedantic -Wall -Wextra -Wmissing-prototypes \
-Werror -Wshadow -Wstrict-overflow -fno-strict-aliasing \
-Wstrict-prototypes -Wwrite-strings \
-Os
all: iblock
iblock: main.c
${CC} -o iblock main.c
${CC} ${CFLAGS} -o iblock main.c
clean:
rm -f iblock
install: iblock
install -o root -g wheel iblock ${PREFIX}/sbin/
test: clean iblock
@printf "hello\n" | nc -4 localhost 666
@printf "hello\n" | nc -6 localhost 666

View File

@ -4,6 +4,7 @@ iblock is an inetd program adding the client IP to a Packet Filter table.
It is meant to be used to block scanner connecting on unused ports.
Upon connection, the IP is added to a PF table and all established connections with this IP are killed. You need to use a PF bloking rule using the table.
# How to use
@ -26,8 +27,8 @@ permit nopass _iblock cmd /sbin/pfctl
Start inetd service with this in `/etc/inetd.conf`:
```
666 stream tcp nowait _iblock /usr/local/bin/iblock iblock
666 stream tcp6 nowait _iblock /usr/local/bin/iblock iblock
666 stream tcp nowait _iblock /usr/local/sbin/iblock iblock
666 stream tcp6 nowait _iblock /usr/local/sbin/iblock iblock
```
You can change the PF table by adding it as a parameter like this:
@ -35,10 +36,12 @@ You can change the PF table by adding it as a parameter like this:
In this example, the parameter `blocklist` will add IPs to the `blocklist` PF table.
```
666 stream tcp nowait _iblock /usr/local/bin/iblock iblock blocklist
666 stream tcp6 nowait _iblock /usr/local/bin/iblock iblock blocklist
666 stream tcp nowait _iblock /usr/local/sbin/iblock iblock blocklist
666 stream tcp6 nowait _iblock /usr/local/sbin/iblock iblock blocklist
```
Default is "iblocked" table.
## Configure packet filter
Use this in `/etc/pf.conf`, choose which ports will trigger the ban from the variable:
@ -65,5 +68,4 @@ In the example I added a label to the block rule, you can use `pfctl -s labels`
# TODO
- make install doing something
- A proper man page

83
main.c
View File

@ -1,57 +1,90 @@
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <err.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/socket.h>
#define DEFAULT_TABLE "iblocked"
#define DEFAULT_TABLE "blocked"
#define TABLE_LEN 128 /* not sure what is pf table name length limit... */
static void __dead
usage(void)
{
fprintf(stderr, "usage: %s [table]\n", getprogname());
exit(1);
}
int main(int argc, char *argv[]){
struct sockaddr_storage sock;
int
main(int argc, char *argv[])
{
struct sockaddr_storage sock = {0};
socklen_t slen = sizeof(sock);
char ip[INET6_ADDRSTRLEN] = {'\0'}; /* INET6_ADDRSTRLEN > INET_ADDRSTRLEN */
char table[TABLE_LEN] = DEFAULT_TABLE;
int status;
const char *table = DEFAULT_TABLE;
int ch, status = 0;
pid_t id;
if (unveil("/usr/bin/doas", "rx") != 0)
err(1, "unveil");
if (pledge("exec inet stdio", NULL) != 0)
if (pledge("exec inet proc 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);
while ((ch = getopt(argc, argv, "")) != -1) {
switch (ch) {
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc > 1)
usage();
if (argc == 1)
table = *argv;
/* get socket structure */
if(getpeername(STDIN_FILENO, (struct sockaddr *)&sock, &slen))
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);
NULL, 0, NI_NUMERICHOST);
if(status != 0) {
syslog(LOG_DAEMON, "getnameinfo error");
if (status != 0) {
syslog(LOG_DAEMON, "getnameinfo error: %s",
gai_strerror(status));
exit(1);
}
syslog(LOG_DAEMON, "blocking %s", ip);
switch(sock.ss_family) {
case AF_INET: /* FALLTHROUGHT */
switch (sock.ss_family) {
case AF_INET: /* FALLTHROUGH */
case AF_INET6:
execlp("/usr/bin/doas", "doas", "/sbin/pfctl", "-t", table, "-T", "add", ip, NULL);
id = fork();
if (id == -1) {
syslog(LOG_DAEMON, "fork error");
exit(1);
} else if (id == 0) {
// child process
syslog(LOG_DAEMON, "blocking %s", ip);
execl("/usr/bin/doas", "doas", "/sbin/pfctl",
"-t", table, "-T", "add", ip, NULL);
} else {
// parent process
wait(NULL);
syslog(LOG_DAEMON, "kill states for %s", ip);
execl("/usr/bin/doas", "doas", "/sbin/pfctl",
"-k", ip, NULL);
}
break;
default:
exit(2);
}
}