Re: idea to block some scanners
> De : mxb [mailto:m...@alumni.chalmers.se], 30 juin 2014 03:26 > Could you please, post updated version to the list? Sure! --- /dev/null Mon Jun 30 07:57:57 2014 +++ tarpitd.c Fri Jun 27 14:01:35 2014 @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2014 Sebastien Leclerc. All rights reserved. + * Copyright (c) 2002-2007 Bob Beck. All rights reserved. + * Copyright (c) 2002 Theo de Raadt. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct con { + int fd; + int af; + struct sockaddr_storage ss; + void *ia; + char addr[32]; + char caddr[32]; + char cport[6]; + time_t r; + time_t s; + char ibuf[8192]; + char *ip; + int il; +} *con; + +void usage(void); +void initcon(struct con *, int, struct sockaddr *); +void closecon(struct con *); +void handler(struct con *); +void getcaddr(struct con *); +int blockhost(char *); +int blocklistener(void); + +struct syslog_data sdata = SYSLOG_DATA_INIT; +struct passwd *pw; + +time_t t; + +#define MAXCON 800 +int maxfiles; +int maxcon = MAXCON; +int clients; +int debug; +int window = 0; +int autoblock = 1; +int pipel[2] = { -1, -1 }; +pid_t pidl = -1; +#define MAXIDLETIME 30 +#define MAXTIME 120 +#define PATH_PFCTL "/sbin/pfctl" + +void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, + "usage: %s [-d] [-c maxcon] [-l address] " + "[-p port] [-w window]\n", + __progname); + + exit(1); +} + +int +blockhost(char *ip) +{ + switch(fork()) { + case -1: + syslog_r(LOG_WARNING, &sdata, "child cannot fork (%m)"); + return (-1); + case 0: + /* child */ + if (-1 == execl(PATH_PFCTL, "pfctl", "-q", "-t", "badguys", "-T", "add", ip, NULL)) { + syslog_r(LOG_WARNING, &sdata, "cannot exec pfctl (%m)"); + return (-2); + } + } + + /* parent */ + return (0); +} + +int blocklistener(void) +{ + int ret = 0; + ssize_t len; + size_t lsize = 0; + char *buf = NULL; + FILE *pf; + + fcntl(pipel[0], F_SETFD, FD_CLOEXEC); + + pf = fdopen(pipel[0], "r"); + if (pf == NULL) { + syslog_r(LOG_WARNING, &sdata, "cannot open pipe (%m)"); + close(pipel[0]); + return(-1); + } + + while (-1 != (len = getline(&buf, &lsize, pf))) { + buf[len - 1] = '\0'; + blockhost(buf); + memset(buf, 0, sizeof buf); + } + + if (ferror(pf)) { + syslog_r(LOG_ERR, &sdata, "child listener aborted (%m)"); + ret = 2; + } + else if (feof(pf)) { + syslog_r(LOG_INFO, &sdata, "child listener terminated normally."); + } + + fclose(pf); + return(ret); +} + +void +getcaddr(struct con *cp) +{ + struct sockaddr_storage spamd_end; + struct sockaddr *sep = (struct sockaddr *) &spamd_end; + socklen_t len = sizeof(struct sockaddr_storage); + int error; + + cp->caddr[0] = '\0'; + cp->cport[0] = '\0'; + if (getsockname(cp->fd, sep, &len) == -1) + return; + error = getnameinfo(sep, sep->sa_len, cp->caddr, sizeof(cp->caddr), + cp->cport, sizeof(cp->cport), NI_NUMERICHOST | NI_NUMERICSERV); + if (error) { + syslog_r(LOG_WARNING, &sdata, "cannot get original destination address."); + cp->caddr[0] = '\0'; + cp->cport[0] = '\0'; + } +} + +void +initcon(struct con *cp, int fd, struct sockaddr *sa) +{ + socklen_t len = sa->sa_len; + time_t tt; + int error; + + time(&tt); + bzero(cp, sizeof(struct con)); + cp->fd = fd; + if (len > sizeof(cp->ss)) + errx(1, "sockaddr size"); + if (sa->sa_family != AF_INET) + errx(1, "not supported yet"); + memcpy(&cp->ss, sa, sa->sa_len)
Re: idea to block some scanners
Could you please, post updated version to the list? //mxb On 27 jun 2014, at 20:09, Leclerc, Sebastien wrote: >> Stuart Henderson , 2014-06-27 11:00 >> >>> +/* Stolen from ftp-proxy */ >> >> Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several >> releases, it has switched to the much easier-to-use divert-to / >> getsockname(). > > And also : > >> Henning Brauer , 2014-06-27 14:07 >> no >> >> DIOCNATLOOK is stupid. I'll celebrate the day when I can kill it. >> Please look at less ancient ftp-proxy/*-proxy code for inspiration. > > Way simpler, indeed! > Thank you > > > --- tarpitd.c.bak Fri Jun 27 13:25:06 2014 > +++ tarpitd.c Fri Jun 27 14:01:35 2014 > @@ -56,21 +56,11 @@ struct con { >int il; > } *con; > > -/* From netinet/in.h, but only _KERNEL_ gets them. */ > -#define satosin(sa)((struct sockaddr_in *)(sa)) > -#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) > -int server_lookup4(struct sockaddr_in *, struct sockaddr_in *, > -struct sockaddr_in *); > -int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *, > -struct sockaddr_in6 *); > - > void usage(void); > void initcon(struct con *, int, struct sockaddr *); > void closecon(struct con *); > void handler(struct con *); > void getcaddr(struct con *); > -int server_lookup(struct sockaddr *, struct sockaddr *, > -struct sockaddr *); > int blockhost(char *); > int blocklistener(void); > > @@ -84,7 +74,6 @@ int maxfiles; > int maxcon = MAXCON; > int clients; > int debug; > -int pfdev; > int window = 0; > int autoblock = 1; > int pipel[2] = { -1, -1 }; > @@ -160,90 +149,11 @@ int blocklistener(void) >return(ret); > } > > -/* Stolen from ftp-proxy */ > -int > -server_lookup(struct sockaddr *client, struct sockaddr *proxy, > -struct sockaddr *server) > -{ > - if (client->sa_family == AF_INET) > - return (server_lookup4(satosin(client), satosin(proxy), > - satosin(server))); > - > - if (client->sa_family == AF_INET6) > - return (server_lookup6(satosin6(client), satosin6(proxy), > - satosin6(server))); > - > - errno = EPROTONOSUPPORT; > - return (-1); > -} > - > -int > -server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy, > -struct sockaddr_in *server) > -{ > - struct pfioc_natlook pnl; > - > - memset(&pnl, 0, sizeof pnl); > - pnl.direction = PF_OUT; > - pnl.af = AF_INET; > - pnl.proto = IPPROTO_TCP; > - memcpy(&pnl.saddr.v4, &client->sin_addr.s_addr, sizeof pnl.saddr.v4); > - memcpy(&pnl.daddr.v4, &proxy->sin_addr.s_addr, sizeof pnl.daddr.v4); > - pnl.sport = client->sin_port; > - pnl.dport = proxy->sin_port; > - > - if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1) > - return (-1); > - > - memset(server, 0, sizeof(struct sockaddr_in)); > - server->sin_len = sizeof(struct sockaddr_in); > - server->sin_family = AF_INET; > - memcpy(&server->sin_addr.s_addr, &pnl.rdaddr.v4, > - sizeof server->sin_addr.s_addr); > - server->sin_port = pnl.rdport; > - > - return (0); > -} > - > -int > -server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy, > -struct sockaddr_in6 *server) > -{ > - struct pfioc_natlook pnl; > - > - memset(&pnl, 0, sizeof pnl); > - pnl.direction = PF_OUT; > - pnl.af = AF_INET6; > - pnl.proto = IPPROTO_TCP; > - memcpy(&pnl.saddr.v6, &client->sin6_addr.s6_addr, sizeof > pnl.saddr.v6); > - memcpy(&pnl.daddr.v6, &proxy->sin6_addr.s6_addr, sizeof pnl.daddr.v6); > - pnl.sport = client->sin6_port; > - pnl.dport = proxy->sin6_port; > - > - if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1) > - return (-1); > - > - memset(server, 0, sizeof(struct sockaddr_in6)); > - server->sin6_len = sizeof(struct sockaddr_in6); > - server->sin6_family = AF_INET6; > - memcpy(&server->sin6_addr.s6_addr, &pnl.rdaddr.v6, > - sizeof server->sin6_addr); > - server->sin6_port = pnl.rdport; > - > - return (0); > -} > - > -/* > - * Get address client connected to, by doing a DIOCNATLOOK call. > - * Uses server_lookup code from ftp-proxy. > - */ > void > getcaddr(struct con *cp) > { >struct sockaddr_storage spamd_end; >struct sockaddr *sep = (struct sockaddr *) &spamd_end; > - struct sockaddr_storage original_destination; > - struct sockaddr *odp = (struct sockaddr *) &original_destination; >socklen_t len = sizeof(struct sockaddr_storage); >int error; > > @@ -251,9 +161,7 @@ getcaddr(struct con *cp) >cp->cport[0] = '\0'; >if (getsockname(cp->fd, sep, &len) == -1) >return; > - if (server_lookup((struct sockaddr *)&cp->ss, sep, odp) != 0) > - return; >
Re: idea to block some scanners
> Stuart Henderson , 2014-06-27 11:00 > > > +/* Stolen from ftp-proxy */ > > Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several > releases, it has switched to the much easier-to-use divert-to / getsockname(). And also : > Henning Brauer , 2014-06-27 14:07 > no > > DIOCNATLOOK is stupid. I'll celebrate the day when I can kill it. > Please look at less ancient ftp-proxy/*-proxy code for inspiration. Way simpler, indeed! Thank you --- tarpitd.c.bak Fri Jun 27 13:25:06 2014 +++ tarpitd.c Fri Jun 27 14:01:35 2014 @@ -56,21 +56,11 @@ struct con { int il; } *con; -/* From netinet/in.h, but only _KERNEL_ gets them. */ -#define satosin(sa)((struct sockaddr_in *)(sa)) -#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) -int server_lookup4(struct sockaddr_in *, struct sockaddr_in *, -struct sockaddr_in *); -int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *, -struct sockaddr_in6 *); - void usage(void); void initcon(struct con *, int, struct sockaddr *); void closecon(struct con *); void handler(struct con *); void getcaddr(struct con *); -int server_lookup(struct sockaddr *, struct sockaddr *, -struct sockaddr *); int blockhost(char *); int blocklistener(void); @@ -84,7 +74,6 @@ int maxfiles; int maxcon = MAXCON; int clients; int debug; -int pfdev; int window = 0; int autoblock = 1; int pipel[2] = { -1, -1 }; @@ -160,90 +149,11 @@ int blocklistener(void) return(ret); } -/* Stolen from ftp-proxy */ -int -server_lookup(struct sockaddr *client, struct sockaddr *proxy, -struct sockaddr *server) -{ - if (client->sa_family == AF_INET) - return (server_lookup4(satosin(client), satosin(proxy), - satosin(server))); - - if (client->sa_family == AF_INET6) - return (server_lookup6(satosin6(client), satosin6(proxy), - satosin6(server))); - - errno = EPROTONOSUPPORT; - return (-1); -} - -int -server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy, -struct sockaddr_in *server) -{ - struct pfioc_natlook pnl; - - memset(&pnl, 0, sizeof pnl); - pnl.direction = PF_OUT; - pnl.af = AF_INET; - pnl.proto = IPPROTO_TCP; - memcpy(&pnl.saddr.v4, &client->sin_addr.s_addr, sizeof pnl.saddr.v4); - memcpy(&pnl.daddr.v4, &proxy->sin_addr.s_addr, sizeof pnl.daddr.v4); - pnl.sport = client->sin_port; - pnl.dport = proxy->sin_port; - - if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1) - return (-1); - - memset(server, 0, sizeof(struct sockaddr_in)); - server->sin_len = sizeof(struct sockaddr_in); - server->sin_family = AF_INET; - memcpy(&server->sin_addr.s_addr, &pnl.rdaddr.v4, - sizeof server->sin_addr.s_addr); - server->sin_port = pnl.rdport; - - return (0); -} - -int -server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy, -struct sockaddr_in6 *server) -{ - struct pfioc_natlook pnl; - - memset(&pnl, 0, sizeof pnl); - pnl.direction = PF_OUT; - pnl.af = AF_INET6; - pnl.proto = IPPROTO_TCP; - memcpy(&pnl.saddr.v6, &client->sin6_addr.s6_addr, sizeof pnl.saddr.v6); - memcpy(&pnl.daddr.v6, &proxy->sin6_addr.s6_addr, sizeof pnl.daddr.v6); - pnl.sport = client->sin6_port; - pnl.dport = proxy->sin6_port; - - if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1) - return (-1); - - memset(server, 0, sizeof(struct sockaddr_in6)); - server->sin6_len = sizeof(struct sockaddr_in6); - server->sin6_family = AF_INET6; - memcpy(&server->sin6_addr.s6_addr, &pnl.rdaddr.v6, - sizeof server->sin6_addr); - server->sin6_port = pnl.rdport; - - return (0); -} - -/* - * Get address client connected to, by doing a DIOCNATLOOK call. - * Uses server_lookup code from ftp-proxy. - */ void getcaddr(struct con *cp) { struct sockaddr_storage spamd_end; struct sockaddr *sep = (struct sockaddr *) &spamd_end; - struct sockaddr_storage original_destination; - struct sockaddr *odp = (struct sockaddr *) &original_destination; socklen_t len = sizeof(struct sockaddr_storage); int error; @@ -251,9 +161,7 @@ getcaddr(struct con *cp) cp->cport[0] = '\0'; if (getsockname(cp->fd, sep, &len) == -1) return; - if (server_lookup((struct sockaddr *)&cp->ss, sep, odp) != 0) - return; - error = getnameinfo(odp, odp->sa_len, cp->caddr, sizeof(cp->caddr), + error = getnameinfo(sep, sep->sa_len, cp->caddr, sizeof(cp->caddr), cp->cport, sizeof(cp->cport), NI_NUMERICHOST | NI_NUMERICSERV); if (error) { syslog_r(LOG_WARNING, &sdata, "cannot get original destination address."); @@ -489,12 +397,6 @@ main(int argc, char *
Re: idea to block some scanners
* Leclerc, Sebastien [2014-06-27 16:40]: > + if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1) no DIOCNATLOOK is stupid. I'll celebrate the day when I can kill it. Please look at less ancient ftp-proxy/*-proxy code for inspiration. -- Henning Brauer, h...@bsws.de, henn...@openbsd.org BS Web Services GmbH, http://bsws.de, Full-Service ISP Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed Henning Brauer Consulting, http://henningbrauer.com/
Re: idea to block some scanners
> DeĀ : Stuart Henderson [mailto:st...@openbsd.org] > > On 2014/06/27 09:58, Leclerc, Sebastien wrote: > > Hi, > > > > Would this piece of code be useful to someone else than me? > > Not sure about base, but it may make sense to add to ports. I'm not familiar with the creation of a port, but I'm willing to learn it when I'll have some spare time. > > > +/* Stolen from ftp-proxy */ > > Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several > releases, it has switched to the much easier-to-use divert-to / getsockname(). You're right, it is from spamd(8) source code, and the comment was copied verbatim.
Re: idea to block some scanners
On 2014/06/27 09:58, Leclerc, Sebastien wrote: > Hi, > > Would this piece of code be useful to someone else than me? Not sure about base, but it may make sense to add to ports. > +/* Stolen from ftp-proxy */ Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several releases, it has switched to the much easier-to-use divert-to / getsockname().
idea to block some scanners
Hi, Would this piece of code be useful to someone else than me? It works with pf's divert-to to block some scanners. It's basically a stripped-down spamd(8), that listens to every TCP connection that is diverted to it, and sends the received data to the great bitbucket in the sky, one byte per second. It also adds the client's IP to a pf table, which can be used to block future connections from the same host. I'm a sysadmin, not a programmer, so comments are welcome! Sebastien Leclerc --- /dev/null Fri Jun 27 09:37:50 2014 +++ tarpitd.c Wed Jun 18 15:29:48 2014 @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2014 Sebastien Leclerc. All rights reserved. + * Copyright (c) 2002-2007 Bob Beck. All rights reserved. + * Copyright (c) 2002 Theo de Raadt. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct con { + int fd; + int af; + struct sockaddr_storage ss; + void *ia; + char addr[32]; + char caddr[32]; + char cport[6]; + time_t r; + time_t s; + char ibuf[8192]; + char *ip; + int il; +} *con; + +/* From netinet/in.h, but only _KERNEL_ gets them. */ +#define satosin(sa)((struct sockaddr_in *)(sa)) +#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) +int server_lookup4(struct sockaddr_in *, struct sockaddr_in *, +struct sockaddr_in *); +int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *, +struct sockaddr_in6 *); + +void usage(void); +void initcon(struct con *, int, struct sockaddr *); +void closecon(struct con *); +void handler(struct con *); +void getcaddr(struct con *); +int server_lookup(struct sockaddr *, struct sockaddr *, +struct sockaddr *); +int blockhost(char *); +int blocklistener(void); + +struct syslog_data sdata = SYSLOG_DATA_INIT; +struct passwd *pw; + +time_t t; + +#define MAXCON 800 +int maxfiles; +int maxcon = MAXCON; +int clients; +int debug; +int pfdev; +int window = 0; +int autoblock = 1; +int pipel[2] = { -1, -1 }; +pid_t pidl = -1; +#define MAXIDLETIME 30 +#define MAXTIME 120 +#define PATH_PFCTL "/sbin/pfctl" + +void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, + "usage: %s [-d] [-c maxcon] [-l address] " + "[-p port] [-w window]\n", + __progname); + + exit(1); +} + +int +blockhost(char *ip) +{ + switch(fork()) { + case -1: + syslog_r(LOG_WARNING, &sdata, "child cannot fork (%m)"); + return (-1); + case 0: + /* child */ + if (-1 == execl(PATH_PFCTL, "pfctl", "-q", "-t", "badguys", "-T", "add", ip, NULL)) { + syslog_r(LOG_WARNING, &sdata, "cannot exec pfctl (%m)"); + return (-2); + } + } + + /* parent */ + return (0); +} + +int blocklistener(void) +{ + int ret = 0; + ssize_t len; + size_t lsize = 0; + char *buf = NULL; + FILE *pf; + + fcntl(pipel[0], F_SETFD, FD_CLOEXEC); + + pf = fdopen(pipel[0], "r"); + if (pf == NULL) { + syslog_r(LOG_WARNING, &sdata, "cannot open pipe (%m)"); + close(pipel[0]); + return(-1); + } + + while (-1 != (len = getline(&buf, &lsize, pf))) { + buf[len - 1] = '\0'; + blockhost(buf); + memset(buf, 0, sizeof buf); + } + + if (ferror(pf)) { + syslog_r(LOG_ERR, &sdata, "child listener aborted (%m)"); + ret = 2; + } + else if (feof(pf)) { + syslog_r(LOG_INFO, &sdata, "child listener terminated normally."); + } + + fclose(pf); + return(ret); +} + +/* Stolen from ftp-proxy */ +int +server_lookup(struct sockaddr *client, struct sockaddr *proxy, +struct sockaddr *server) +{ + if (client->sa_family == AF_INET) + return (server_lookup4(satosin(client), satosin(proxy), + satosin(server))); + + if (clien