Compare commits
20 Commits
Author | SHA1 | Date |
---|---|---|
Omar Polo | 5ac1e2631b | |
solene | 550cfca6d1 | |
Solene Rapenne | f6e72657a5 | |
prx | b95e736dc7 | |
prx | a2702bad84 | |
solene | 747a833df3 | |
Solene Rapenne | 1f21555152 | |
solene | f272f53c0c | |
prx | 7910b7ea11 | |
solene | 1a60f738f2 | |
prx | ff5ff21ca5 | |
prx | 8fe70f68e8 | |
prx | 3cadbbe7df | |
prx | 9b755ab627 | |
prx | 28eb2bfbeb | |
prx | 7c1edb0feb | |
prx | 2b226c9a02 | |
prx | f9d12c9ef5 | |
prx | 7f474df2ee | |
Solene Rapenne | ee7a713fc9 |
17
Makefile
17
Makefile
|
@ -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
|
||||
|
|
12
README.md
12
README.md
|
@ -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
83
main.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue