• rssfeed

pure-ftpd with geoip

During the last few weeks we are experiencing compromised FTP accounts within our production. These accounts seem to be stolen from infected Windows client machines, infected by malware or trojans. As far as I know the issues, everyone of them is using Total Commander… TC seems to save the credentials in plain text form, unencrypted. Fine.

I have been going through pure-ftpd log to gather ips that had been used to upload files. I’ve found that most of them were outside our country, China, Romania, Russia, etc. So I decided to limit users set and allow only ips from Czech Republic. I wanted to go with iptables geoip module, which is working very fine. But I have found geoip patch for pure-ftpd. I have corrected it a little bit and finally created RPM packages for Centos4/5. You can find the packages within my repository. Feel free to use…

Packages

http://fs12.vsb.cz/hrb33/el5/hrb/stable/i386/repoview/pure-ftpd.html
http://fs12.vsb.cz/hrb33/el5/hrb/stable/x86_64/repoview/pure-ftpd.html

http://fs12.vsb.cz/hrb33/el4/hrb/stable/i386/repoview/pure-ftpd.html
http://fs12.vsb.cz/hrb33/el4/hrb/stable/x86_64/repoview/pure-ftpd.html

The patch

diff -ur pure-ftpd-1.0.22/src/ftpd.c pure-ftpd-1.0.22-geoip/src/ftpd.c
--- pure-ftpd-1.0.22/src/ftpd.c 2009-09-17 09:38:04.000000000 +0200
+++ pure-ftpd-1.0.22-geoip/src/ftpd.c   2009-09-17 09:34:03.000000000 +0200
@@ -34,6 +34,8 @@
 # include "osx-extensions.h"
 #endif
 
+#include "GeoIP.h"
+
 #ifdef WITH_GSSAPI
 # include "auth_gssapi.h"
 #endif
@@ -4818,7 +4820,7 @@
 die(421, LOG_ERR, MSG_GETPEERNAME ": %s" , strerror(errno));
 }
 fourinsix(&peer);
-    if (checkvalidaddr(&peer) == 0) {
+    if (checkvalidaddr(&peer) == 0 || STORAGE_FAMILY(ctrlconn) != AF_INET) {
 die(425, LOG_ERR, MSG_INVALID_IP);
 }
 #ifndef DONT_LOG_IP
@@ -4854,6 +4856,37 @@
 *host = '?';
 host[1] = 0;
 #endif
+    do {
+        char line[LINE_MAX];
+        GeoIP *gi;
+        const char *country;
+        char *sep;
+        int found = 0;
+        FILE *fp;
+
+        gi = GeoIP_new(GEOIP_STANDARD);
+        country = GeoIP_country_code_by_name(gi, host);
+        if (country == NULL || *country == 0 ||
+            !(fp = fopen(CONFDIR "/pureftpd-restricted-countries.txt", "r"))) {
+            break;
+        }
+        while (fgets(line, sizeof line, fp) != NULL) {
+            if (*line == '#') {
+                continue;
+            }
+            if ((sep = strchr(line, '\n')) != NULL) {
+                *sep = 0;
+            }
+            if (strcasecmp(line, country) == 0) {
+                found++;
+                break;
+            }
+        }
+        fclose(fp);
+        if (found == 0) {
+            die(425, LOG_ERR, MSG_INVALID_IP);
+        }
+    } while(0);
 iptropize(&peer);
 logfile(LOG_INFO, MSG_NEW_CONNECTION, host);
 
diff -ur pure-ftpd-1.0.22/src/Makefile.am pure-ftpd-1.0.22-geoip/src/Makefile.am
--- pure-ftpd-1.0.22/src/Makefile.am    2006-04-25 10:15:54.000000000 +0200
+++ pure-ftpd-1.0.22-geoip/src/Makefile.am      2009-09-17 09:37:14.000000000 +0200
@@ -16,7 +16,7 @@
 
 pure_ftpd_LDADD = \
        ../puredb/src/libpuredb_read.a \
-       @LDAP_SSL_LIBS@ @GETLOADAVG_LIBS@ @BONJOUR_LDADD@
+       @LDAP_SSL_LIBS@ @GETLOADAVG_LIBS@ @BONJOUR_LDADD@ -lGeoIP
 
 pure_ftpd_CFLAGS = -DINCLUDE_IO_WRAPPERS=1
 
diff -ur pure-ftpd-1.0.22/src/Makefile.in pure-ftpd-1.0.22-geoip/src/Makefile.in
--- pure-ftpd-1.0.22/src/Makefile.in    2006-04-25 10:45:12.000000000 +0200
+++ pure-ftpd-1.0.22-geoip/src/Makefile.in      2009-09-17 09:35:43.000000000 +0200
@@ -221,7 +221,7 @@
 target_alias = @target_alias@
 pure_ftpd_LDADD = \
        ../puredb/src/libpuredb_read.a \
-       @LDAP_SSL_LIBS@ @GETLOADAVG_LIBS@ @BONJOUR_LDADD@
+       @LDAP_SSL_LIBS@ @GETLOADAVG_LIBS@ @BONJOUR_LDADD@ -lGeoIP
 
 pure_ftpd_CFLAGS = -DINCLUDE_IO_WRAPPERS=1
 pure_ftpd_SOURCES = \

 
 
 

Leave a Reply