Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

讓 vsftpd 3.0.3 在 local 網路連線時, 不使用 pasv_address 的設定
post by tommy @ 01 十月, 2017 09:26

近來 (應該也有一陣子了) 發現用 FileZilla 連到家裡的 ftp 時, 使用 TLS 連線會每隔 20 秒出現一次逾時錯誤訊息就離線. 而且在部網路直接連線時, 會有一樣的問題, 應該跟 firewall 沒關係. 在 FileZilla 的討論區有提到 Pure-ftpd <= 1.0.38 時會有問題, 不過家裡的伺服器應該是 1.0.46 (印象中, 以前使用 1.0.3x 的版本並沒有這個錯誤). 所以試著換了 vsftpd 3.0.3 來使用, 還真的就不會出現這個訊息了.

不過換上 vsftpd 之後, 就碰到之前在 pure-ftpd 時相同的問題, 就是使用 passive 模式時, 如果指定使用外部的 ip 之後, 會造成內部的連線也收到外部的 ip 而無法使用. 如果不指定外部 ip 時, 會造成外部的連線收到內部的 ip 而無法連線 (使用 filezilla 時, 這情形會用連線的 ip 取代, 可以繼續使用).

所以... 就把之前給 pure-ftpd 的 patch 改了一下給 vsftpd 用:

diff --show-c-function -Nur vsftpd-3.0.3.orig/main.c vsftpd-3.0.3/main.c
--- vsftpd-3.0.3.orig/main.c 2012-09-16 12:27:13.000000000 +0800
+++ vsftpd-3.0.3/main.c 2017-09-28 21:10:16.620440681 +0800
@@ -32,6 +32,70 @@ static void session_init(struct vsf_sess
static void env_init(void);
static void limits_init(void);
 
+// add by twu2 20170928 begin
+#include <stdio.h>
+#include "filestr.h"
+// check local net in /etc/localnet
+static int check_local_net(const struct vsf_sysutil_sockaddr * const addr)
+{
+ unsigned long a1 = 0U;
+ unsigned long a2 = 0U;
+ unsigned long mask = 0U;
+ unsigned int b1, b2, b3, b4;
+ unsigned int m1, m2, m3, m4;
+ static struct mystr s_curr_line_str;
+ unsigned int pos = 0;
+ struct mystr localnet_file = INIT_MYSTR;
+ int retval = -1;
+ const void* p_v4addr;
+ int is_ipv6;
+ const char *ip;
+ int is_local;
+
+ if (!addr) return 0;
+ is_ipv6 = vsf_sysutil_sockaddr_is_ipv6(addr);
+ if (is_ipv6) {
+ p_v4addr = vsf_sysutil_sockaddr_ipv6_v4(addr);
+ if (!p_v4addr) return 0;
+ ip = vsf_sysutil_inet_ntoa(p_v4addr);
+ }
+ else
+ ip = vsf_sysutil_inet_ntop(addr);
+ if (!ip) return 0;
+ b1 = b2 = b3 = b4 = 0;
+ if ((sscanf(ip, "%u.%u.%u.%u", &b1, &b2, &b3, &b4) != 4) ||
+ b1 > 255U || b2 > 255U || b3 > 255U || b4 > 255U ||
+ (b1 | b2 | b3 | b4) == 0U)
+ return 0;
+ a1 = b1 << 24 | b2 << 16 | b3 << 8 | b4;
+ retval = str_fileread(&localnet_file, tunable_local_net_file,
+ VSFTP_CONF_FILE_MAX);
+ // no localnet file
+ if (vsf_sysutil_retval_is_error(retval))
+ return 0;
+ is_local = 0;
+ while (str_getline(&localnet_file, &s_curr_line_str, &pos)) {
+ b1 = b2 = b3 = b4 = m1 = m2 = m3 = m4 = 0;
+ if ((sscanf(str_getbuf(&s_curr_line_str), "%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;
+ }
+ }
+ str_free(&localnet_file);
+ return is_local;
+}
+// add by twu2 20170928 end
+
int
main(int argc, const char* argv[])
{
@@ -67,6 +131,12 @@ main(int argc, const char* argv[])
0, 0, 0, 0, 0, INIT_MYSTR, 0, -1, -1,
/* Login fails */
0
+ // add by twu2 20170928 begin
+ /* is_local */
+ ,0
+ /* nomaxrate */
+ ,0
+ // add by twu2 20170928 end
};
int config_loaded = 0;
int i;
@@ -243,6 +313,9 @@ main(int argc, const char* argv[])
tunable_chown_uploads = 0;
}
}
+ // add by twu2 20170928 begin
+ the_session.is_local = check_local_net(the_session.p_remote_addr);
+ // add by twu2 20170928 end
if (tunable_one_process_model)
{
vsf_one_process_start(&the_session);
diff --show-c-function -Nur vsftpd-3.0.3.orig/parseconf.c vsftpd-3.0.3/parseconf.c
--- vsftpd-3.0.3.orig/parseconf.c 2017-09-28 14:40:29.000000000 +0800
+++ vsftpd-3.0.3/parseconf.c 2017-09-28 21:10:31.892567245 +0800
@@ -158,6 +158,10 @@ parseconf_str_array[] =
{ "ftpd_banner", &tunable_ftpd_banner },
{ "banned_email_file", &tunable_banned_email_file },
{ "chroot_list_file", &tunable_chroot_list_file },
+ // add by twu2 20170928 begin
+ { "local_net_file", &tunable_local_net_file },
+ { "nomaxrate_list_file", &tunable_nomaxrate_list_file },
+ // add by twu2 20170928 end
{ "pam_service_name", &tunable_pam_service_name },
{ "guest_username", &tunable_guest_username },
{ "userlist_file", &tunable_userlist_file },
diff --show-c-function -Nur vsftpd-3.0.3.orig/postlogin.c vsftpd-3.0.3/postlogin.c
--- vsftpd-3.0.3.orig/postlogin.c 2017-09-28 14:40:29.000000000 +0800
+++ vsftpd-3.0.3/postlogin.c 2017-09-28 22:27:59.791545391 +0800
@@ -94,6 +94,10 @@ process_post_login(struct vsf_session* p
vsf_sysutil_set_umask(tunable_local_umask);
p_sess->bw_rate_max = tunable_local_max_rate;
}
+ // modified by twu2 20170928 begin
+ if (p_sess->nomaxrate)
+ p_sess->bw_rate_max = 0;
+ // modified by twu2 20170928 end
if (p_sess->is_http)
{
handle_http(p_sess);
@@ -606,8 +610,10 @@ handle_pasv(struct vsf_session* p_sess,
str_append_text(&s_pasv_res_str, "|)");
vsf_cmdio_write_str(p_sess, FTP_EPSVOK, &s_pasv_res_str);
return;
- }
- if (tunable_pasv_address != 0)
+ }
+ // modified by twu2 20170928 begin
+ if (tunable_pasv_address != 0 && p_sess->is_local == 0)
+ // modified by twu2 20170928 end
{
vsf_sysutil_sockaddr_alloc_ipv4(&s_p_sockaddr);
/* Report passive address as specified in configuration */
@@ -1829,6 +1835,12 @@ handle_stat(struct vsf_session* p_sess)
vsf_cmdio_write_hyphen(p_sess, FTP_STATOK, "FTP server status:");
vsf_cmdio_write_raw(p_sess, " Connected to ");
vsf_cmdio_write_raw(p_sess, str_getbuf(&p_sess->remote_ip_str));
+ // modified by twu2 20170928 begin
+ if (p_sess->is_local)
+ vsf_cmdio_write_raw(p_sess, ", (LAN)");
+ else
+ vsf_cmdio_write_raw(p_sess, ", (WAN)");
+ // modified by twu2 20170928 end
vsf_cmdio_write_raw(p_sess, "\r\n");
vsf_cmdio_write_raw(p_sess, " Logged in as ");
vsf_cmdio_write_raw(p_sess, str_getbuf(&p_sess->user_str));
diff --show-c-function -Nur vsftpd-3.0.3.orig/session.h vsftpd-3.0.3/session.h
--- vsftpd-3.0.3.orig/session.h 2012-04-05 09:27:19.000000000 +0800
+++ vsftpd-3.0.3/session.h 2017-09-28 21:09:03.871838330 +0800
@@ -99,6 +99,10 @@ struct vsf_session
int ssl_slave_fd;
int ssl_consumer_fd;
unsigned int login_fails;
+ // add by twu2 20170928 begin
+ int is_local;
+ int nomaxrate;
+ // add by twu2 20170928 end
};
 
#endif /* VSF_SESSION_H */
diff --show-c-function -Nur vsftpd-3.0.3.orig/tunables.c vsftpd-3.0.3/tunables.c
--- vsftpd-3.0.3.orig/tunables.c 2017-09-28 14:40:29.000000000 +0800
+++ vsftpd-3.0.3/tunables.c 2017-09-28 21:10:58.748789905 +0800
@@ -121,6 +121,10 @@ const char* tunable_nopriv_user;
const char* tunable_ftpd_banner;
const char* tunable_banned_email_file;
const char* tunable_chroot_list_file;
+// add by twu2 20170928 begin
+const char* tunable_local_net_file;
+const char* tunable_nomaxrate_list_file;
+// add by twu2 20170928 end
const char* tunable_pam_service_name;
const char* tunable_guest_username;
const char* tunable_userlist_file;
@@ -268,6 +272,10 @@ tunables_load_defaults()
install_str_setting(0, &tunable_ftpd_banner);
install_str_setting("/etc/vsftpd.banned_emails", &tunable_banned_email_file);
install_str_setting("/etc/vsftpd.chroot_list", &tunable_chroot_list_file);
+ // add by twu2 20170928 begin
+ install_str_setting("/etc/localnet", &tunable_local_net_file);
+ install_str_setting("/etc/vsftpd.nomaxrate_list", &tunable_nomaxrate_list_file);
+ // add by twu2 20170928 end
install_str_setting("vsftpd", &tunable_pam_service_name);
install_str_setting("ftp", &tunable_guest_username);
install_str_setting("/etc/vsftpd.user_list", &tunable_userlist_file);
diff --show-c-function -Nur vsftpd-3.0.3.orig/tunables.h vsftpd-3.0.3/tunables.h
--- vsftpd-3.0.3.orig/tunables.h 2017-09-28 14:40:29.000000000 +0800
+++ vsftpd-3.0.3/tunables.h 2017-09-28 20:57:15.750028392 +0800
@@ -124,6 +124,10 @@ extern const char* tunable_nopriv_user;
extern const char* tunable_ftpd_banner;
extern const char* tunable_banned_email_file;
extern const char* tunable_chroot_list_file;
+// add by twu2 20170928 begin
+extern const char* tunable_local_net_file;
+extern const char* tunable_nomaxrate_list_file;
+// add by twu2 20170928 end
extern const char* tunable_pam_service_name;
extern const char* tunable_guest_username;
extern const char* tunable_userlist_file;
diff --show-c-function -Nur vsftpd-3.0.3.orig/twoprocess.c vsftpd-3.0.3/twoprocess.c
--- vsftpd-3.0.3.orig/twoprocess.c 2012-09-16 15:15:49.000000000 +0800
+++ vsftpd-3.0.3/twoprocess.c 2017-09-29 23:18:56.487053338 +0800
@@ -358,6 +358,9 @@ process_login_req(struct vsf_session* p_
if (do_chroot)
{
do_chroot = 0;
+ // add by twu2 20170928 begin
+ tunable_idle_session_timeout = 0;
+ // add by twu2 20170928 end
}
else
{
@@ -366,6 +369,23 @@ process_login_req(struct vsf_session* p_
}
str_free(&chroot_list_file);
}
+ // add by twu2 20170928 begin
+ p_sess->nomaxrate = 0;
+ if (tunable_nomaxrate_list_file)
+ {
+ struct mystr nomaxrate_list_file = INIT_MYSTR;
+ int retval;
+
+ retval = str_fileread(&nomaxrate_list_file, tunable_nomaxrate_list_file,
+ VSFTP_CONF_FILE_MAX);
+ if (!vsf_sysutil_retval_is_error(retval))
+ {
+ if (str_contains_line(&nomaxrate_list_file, &p_sess->user_str))
+ p_sess->nomaxrate = 1;
+ }
+ str_free(&nomaxrate_list_file);
+ }
+ // add by twu2 20170928 end
common_do_login(p_sess, &p_sess->user_str, do_chroot, 0);
}
break;

 

檔案可以在這兒抓: https://www.teatime.com.tw/~tommy/mypatch/vsftpd-3.0.3-localnet.patch  

patch 的內容有三個部份:

 

  1. 主要是上面提到的 pasv_address 會依據 /etc/localnet 的內容決定是否使用 .
  2. 檢查 /etc/vsftpd.nomaxrate_list, 如果在裡頭就不限制傳輸的速度
  3. 如果預設是 chroot, 而列在 /etc/vsftpd.chroot_list 是不使用 chroot 時, 則這些使用者也不會有 idle_timeout 的限制
這些應該是之前也有寫給 pure-ftpd 使用的修改, 換回 vsftpd 之後, 順便就改回來了.

 

Del.icio.us Furl HEMiDEMi Technorati MyShare
迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 53 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS