记vsftpd虚拟用户登录返回530 Login incorrect解决过程

遇到的问题

       最近需要在Ubuntu18.04上编译并安装vsftpd,从官网http://www.linuxfromscratch.org/blfs/view/svn/server/vsftpd.html下载vsftpd-3.0.3.tar.gz后,用源码编译成功了vsftpd,配置好ftp虚拟用户后,输入用户名和密码后,发现一直返回530 Login incorrect。

解决问题的过程:

     1. 在IP为192.168.1.264的Ubuntu18.04上,

         1.1 tar -zxf vsftpd-3.0.3.tar.gz

         1.2 cd vsftpd-3.0.3

         1.3 make

         1.4 编译成功后,会在当前目录生成一个vsftpd可执行文件

         1.5 在/etc/vsftpd.conf中配置ftp虚拟用户(网上有很多配置vsftpd虚拟用户的资料),更权威的配置过程见

             ./vsftpd-3.0.3/EXAMPLE/VIRTUAL_USERS/README

     2. 在win7上的cmd命令行,

          2.1 输入"ftp",然后回车,进入ftp命令行模式

          2.2 输入 open 192.168.1.264 21,然后回车

          2.3 要求输入用户名 User (192.168.1.264:(none)): guoke,然后回车,回显 331 Please specify the password.

          2.4 输入密码 Password: 123456,回车后,回显 530 Login incorrect. Login failed.

上面2.4反复试过多次,都是报同样的错误,最后实在没办法,只有上gdb,在调试过程中发现,vsftpd有两种进程工作方式,一种是主进程调用vsf_one_process_start生成一个子进程,另外一种是主进程调用vsf_two_process_start生成两个子进程,好巧不巧,vsftpd的虚拟用户是第二种方式。然后就是在Makefile中加上-g参数编译debug版本调试,特别注意需要删掉 LINK=-Wl,-s,这里的-s会去掉生成文件中的函数名,如果不删掉,会导致gdb调试时加载不了源代码信息。接下来就是把3个进程都用gdb attach PID上,找断点,下断点,先从源码中找到所有出现“Login incorrect”的地方下断,逐渐缩小范围。最后发现是两个子进程中的一个进程老是进入 ./vsftpd/vsftpd-3.0.3/sysdeputil.c的 vsf_sysdep_check_auth 函数里面

#ifndef VSF_SYSDEP_HAVE_PAM //问题就出现在这个 VSF_SYSDEP_HAVE_PAM上

int vsf_sysdep_check_auth(struct mystr* p_user_str,
                      const struct mystr* p_pass_str,
                      const struct mystr* p_remote_host)
{
  const char* p_crypted;
  const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str));
  (void) p_remote_host;
  if (p_pwd == NULL) //由于ftp虚拟用户是不存在的用户,所以p_pwd永远为NULL
  {
    return 0;
  }
......
}
......
#else //这个else才是pam验证函数
.......
int vsf_sysdep_check_auth(struct mystr* p_user_str,
                      const struct mystr* p_pass_str,
                      const struct mystr* p_remote_host)
{
  int retval = -1;
  pam_item_t item;
  const char* pam_user_name = 0;
......
}
......
#endif

最后读了几次代码才反应过来,是这个 #ifndef VSF_SYSDEP_HAVE_PAM 出了问题,然后顺藤摸瓜,发现是

./vsftpd-3.0.3/dummyinc/security/pam_appl.h这个文件里面 #undef VSF_SYSDEP_HAVE_PAM 取消定义了,最最后,锁定了Makefile里面的 IFLAGS  = -idirafter dummyinc,这个gcc参数-idirafter表示如果gcc在其他地方找不到 #include "./security/pam_appl.h",最后就在dummyinc目录下面找。问题源头找到了,接下来就是如何解决该问题了,解决这个问题有两种方式,一种是直接注释掉./vsftpd-3.0.3/dummyinc/security/pam_appl.h,但这是下策。另一种是发现vsf_findlibs.sh里面有一个"-lpam"选项,原来vsftpd在这个地方埋了一个坑,如果系统中未找到 libpam.so,就不会编译pam。然后使用apt-get install libpam0g-dev装上对应的开发包后,然后编译的时候使用 make LIBS="-lpam -lcap",结果就可以使用虚拟账户登录了。

总结:

   1.  "在源码面前没有秘密可言" ----- 侯捷

    2. vsftpd默认是在Redhat上编写并安装的软件,不要天真的认为Ubuntu和Redhat都是Linux系统,同一个软件在两个系统上的表现就都会一样。

你可能感兴趣的:(记vsftpd虚拟用户登录返回530 Login incorrect解决过程)