让 pure-ftpd 的 -P (forcepassiveip) 参数,只用在远端连接
pureftpd 如果配置了远端 -p (--passiveportrange) 模式后,在内网连接时无法连接的问题,可以通过修改以下代码重新编译解决问题 创建 /etc/localnet 文件,该文件格式为 AAA.BBB.CCC.DDD/WWW...
pureftpd 如果配置了远端 -p (--passiveportrange) 模式后,在内网连接时无法连接的问题,可以通过修改以下代码重新编译解决问题。
创建 /etc/localnet 文件,该文件格式为:
AAA.BBB.CCC.DDD/WWW.XXX.YYY.ZZZ 如: 192.168.0.0/255.255.0.0
diff -Nur src.orig/ftpd.c src.patch/ftpd.c
--- src.orig/ftpd.c 2006-06-12 18:44:25.000000000 +0800
+++ src.patch/ftpd.c 2006-06-12 22:52:37.590994047 +0800
@@ -405,6 +405,48 @@
(void) title;
}
+// add by twu2 20060612 begin
+// check local net in /etc/localnet
+static void check_local_net(const struct sockaddr_storage * const addr)
+{
+ FILE *fp;
+ unsigned long a1 = 0U;
+ unsigned long a2 = 0U;
+ unsigned long mask = 0U;
+ unsigned int b1, b2, b3, b4;
+ unsigned int m1, m2, m3, m4;
+ char buf[1024];
+
+ if (addr == NULL) return;
+ // only for IPV4 now
+ if (STORAGE_FAMILY(*addr) != AF_INET) return;
+ a1 = ntohl(STORAGE_SIN_ADDR(*addr));
+ fp = fopen("/etc/localnet", "rt");
+ // no localnet file
+ if (fp == NULL) return;
+ while (1) {
+ if (fgets(buf, 1024, fp) == NULL) break;
+ b1 = b2 = b3 = b4 = m1 = m2 = m3 = m4 = 0;
+ if ((sscanf(buf, "%u.%u.%u.%u/%u.%u.%u.%u", &b1, &b2, &b3, &b4, &m1, &m2, &m3, &m4) != 8) ||
+ b1 > 255U || b2 > 255U || b3 > 255U || b4 > 255U ||
+ (b1 | b2 | b3 | b4) == 0U ||
+ m1 > 255U || m2 > 255U || m3 > 255U || m4 > 255U ||
+ (m1 | m2 | m3 | m4) == 0U)
+ continue;
+ a2 = b1 << 24 | b2 << 16 | b3 << 8 | b4;
+ mask = m1 << 24 | m2 << 16 | m3 << 8 | m4;
+ // correct format
+ if ((a1 & mask) == (a2 & mask)) {
+ // same subnet
+ is_local = 1;
+ break;
+ }
+ }
+ fclose(fp);
+ return;
+}
+// add by twu2 20060612 end
+
/* Check whether an address is valid, return 1 if ok, 0 otherwise.
* Unfortunately, multicasting with the FTP protocol is impossible,
* you have to use things like MTP instead. So prohibit multicast.
@@ -2123,7 +2165,11 @@
}
switch (psvtype) {
case 0:
- if (STORAGE_FAMILY(force_passive_ip) == 0) {
+// add by twu2 20060612 begin
+ // if the connection from local subnet, don't do force passive ip convert
+ //if (STORAGE_FAMILY(force_passive_ip) == 0) {
+ if (is_local || STORAGE_FAMILY(force_passive_ip) == 0) {
+// add by twu2 20060612 end
a = ntohl(STORAGE_SIN_ADDR(dataconn));
} else if (STORAGE_FAMILY(force_passive_ip) == AF_INET6) {
(void) close(datafd);
@@ -4448,6 +4494,9 @@
die(421, LOG_ERR, MSG_GETPEERNAME ": %s" , strerror(errno));
}
fourinsix(&peer);
+// add by twu2 20060612 begin
+ check_local_net(&peer);
+// add by twu2 20060612 end
if (checkvalidaddr(&peer) == 0) {
die(425, LOG_ERR, MSG_INVALID_IP);
}
@@ -4486,6 +4535,9 @@
#endif
iptropize(&peer);
logfile(LOG_INFO, MSG_NEW_CONNECTION, host);
+// add by twu2 20060612 begin
+ logfile(LOG_INFO, is_local == 1 ? "from local" : "from remote");
+// add by twu2 20060612 end
#ifndef NO_BANNER
# ifdef BORING_MODE
diff -Nur src.orig/globals.h src.patch/globals.h
--- src.orig/globals.h 2006-02-15 16:55:00.000000000 +0800
+++ src.patch/globals.h 2006-06-12 21:34:39.361685659 +0800
@@ -73,6 +73,9 @@
GLOBAL0(signed char force_ls_a);
GLOBAL0(struct sockaddr_storage peer);
GLOBAL0(struct sockaddr_storage force_passive_ip);
+// add by twu2 20060612 begin
+GLOBAL(signed char is_local, 0);
+// add by twu2 20060612 end
GLOBAL0(const char *force_passive_ip_s);
GLOBAL0(unsigned short int peerdataport);
GLOBAL0(double maxload);
无评论