我有一个 ftp 客户端(.NET 应用程序,我没有其源代码),它只执行主动模式,需要将数据推送到仅支持被动模式的设备 ftp 服务器。
我无法修改任何一端的软件;但其间的一切都是公平的游戏。(路由,Windows 或 Linux 软件,防火墙技巧......)
有没有什么 ftp 代理软件?或者有什么我可以尝试的解决方案?
答案1
有(或者曾经有?)一个非常好的守护进程叫做SuSE 代理套件。它拦截 FTP 流量并允许将 ftp 客户端重定向到某个特定的后端服务器,如果我没记错的话,它还允许主动<->被动转换。我在相当繁重的环境中使用该程序多年,没有遇到任何问题。
不幸的是我的旧书签(http://proxy-suite.suse.de) 似乎会重定向到 Novell 的页面。几个软件包存储库(快速谷歌搜索后发现是 FreeBSD、Debian)似乎仍包含该软件,因此您可能还有希望。
FreshPorts 似乎对该软件有一个很好的描述:
http://www.freshports.org/net/proxy-suite/
编辑:还有一件事。我不知道这个小问题后来是否被修补了(我上次使用这个东西是在 2004 年),但默认情况下,proxy-suite 以 root 身份运行,因为它需要绑定到低端口。而且它以 Really Root 身份运行,因为它没有利用 Linux能力。
今天应该可以通过设置上限命令如下:
sudo setcap 'cap_net_bind_service=+ep' /path/to/file
但是如果这不起作用(即使功能确实存在,但当我修补代理套件时 setcap 命令并不常见),这里还有另一种解决方法。
早在 2004 年左右,我写了一个小补丁,删除了除以下之外的所有功能:CAP_NET_BIND_SERVICE启动后立即安装,这样即使是一些潜在的安全漏洞也会变得不那么危险。通常情况下,您可能不需要此补丁,但如果您患有这种称为“安全偏执症”的疾病,并且您的文件传输发生在互联网的某些黑暗角落之间,而不是您舒适的办公室局域网之间,那么此补丁可能是一个好主意。
要查看 ftp-proxy 是否以完全 root 权限运行,请检查获取pcaps返回如下内容:
yourserver root# getpcaps `pidof ftp-proxy`
Capabilities for `16982': =eip cap_setpcap-eip
修补后的版本应返回如下内容:
yourserver root# getpcaps `pidof ftp-proxy`
Capabilities for `9522': = cap_net_bind_service+ep
最后,这是我数百万年前写的补丁,我希望它仍然可以应用。
--- common/com-misc.c.orig 2006-11-20 13:54:59.000000000 +0200
+++ common/com-misc.c 2006-11-20 14:40:47.000000000 +0200
@@ -36,0 +37 @@
+#include <sys/capability.h>
@@ -748,0 +750,18 @@
+ /*
+ * If running as root, drop all the privileges except CAP_NET_BIND
+ */
+ if (geteuid() == 0) {
+ cap_t caps = cap_init();
+ static cap_value_t capv[] = {CAP_NET_BIND_SERVICE};
+ const int numcaps = sizeof(capv) / sizeof(capv[0]);
+ if (caps == NULL)
+ syslog_error("cap_init() failed; errno = %d", errno);
+ if (cap_set_flag(caps, CAP_PERMITTED, numcaps, capv, CAP_SET) < 0)
+ syslog_error("Could not set permitted capabilities;
errno = %d", errno);
+ if (cap_set_flag(caps, CAP_EFFECTIVE, numcaps, capv, CAP_SET) < 0)
+ syslog_error("Could not set effective capabilities;
errno = %d", errno);
+ if (cap_set_proc(caps) < 0)
+ syslog_error("Could not apply capability set; errno =
%d", errno);
+ cap_free(caps);
+ }
+