Centos7中配置vsftpd对接LDAP(域控)

背景与需求

公司内部使用ftp进行文件共享,之前使用的是公共账号,导致账号密码到处传播,权限难以管控。因此,计划将FTP服务对接LDAP(公司内部的域控), 实现用个人域账号登录。

具体需求

  • 域账号登录
  • 未经授权的,可以登录FTP,但无权限访问(共享的)内容

实施

环境描述

操作系统

# lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.9.2009 (Core)
Release:        7.9.2009
Codename:       Core

具体实施步骤

步骤概述
(1) 安装基础包
(2) 配置vsftp配置
(3) 调试连接ldap配置

步骤1 安装基础包

# yum install nscd nss-pam-ldapd  -y
# yum -y install vsftpd ftp openldap-clients

步骤2 配置vsftp配置

先贴出我的配置

# cat vsftpd/vsftpd.conf 
use_localtime=YES
listen=YES
connect_from_port_20=YES
ftpd_banner=Welcome to virtual FTP service.
anonymous_enable=NO
local_enable=YES
write_enable=NO
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
chroot_local_user=YES
local_umask=022
guest_enable=YES
guest_username=compiler

tcp_wrappers=YES

use_localtime=yes
max_per_ip=20

pasv_enable=YES
pasv_min_port=3001
pasv_max_port=5100

idle_session_timeout=600
allow_writeable_chroot=YES

pam_service_name=vsftpd                     # 这个指重点配置,对应/etc/pam.d/vsftpd 文件
xferlog_enable=YES
xferlog_file=/var/log/vsftpd/xferlog.log
dual_log_enable=yes


#虚拟用户和本地用户有相同的权限
virtual_use_local_privs=YES
user_sub_token=$USER
local_root=/home/anonymous                  # 没有授权的用户,统一的root目录(无内容)
user_config_dir=/etc/vsftpd/vusers          # 这里放已授权用户的配置,控制用户的root目录

anon_world_readable_only=YES
anon_upload_enable=NO
anon_mkdir_write_enable=YES
anon_other_write_enable=NO

# cat /etc/pam.d/vsftpd            # 配置使用ldap验证     
#%PAM-1.0
auth required /usr/lib64/security/pam_ldap.so
account required /usr/lib64/security/pam_ldap.so

我先在/etc/vsftpd/vusers 创建一个测试账号文件,假定共享的目录为/opt, 也就是所有授权的用户的root目录是/opt

# mkdir -p /etc/vsftpd/vusers
# cd /etc/vsftpd/vusers
# vim pcan1250 
local_root=/opt

下面就是配置去连接LDAP了。

步骤3 配置,调试连接LDAP

直接启动vsftpd的话,现在访问ftp, 在操作系统日志里可以看到以下报错

# tail -f /var/log/secure
Sep 18 15:30:21 szvxl15487 vsftpd[311630]: pam_ldap(vsftpd:auth): Authentication failure; user=pcan1254
Sep 18 15:48:51 szvxl15487 vsftpd[316172]: pam_ldap(vsftpd:auth): error opening connection to nslcd: No such file or directory

那应该就是要用到nslcd 服务了。先配置一下这个服务, 配置文件为/etc/nslcd.conf, 以下是我的配置

# cat /etc/nslcd.conf
uid nslcd
gid ldap
uri ldap://xxx            # 域控地址,根据自己实际情况填
#ldap_version 3
base DC=mydc,DC=xyz       # 根据自己的实际情况填写
binddn  CN=xxxx,OU=vApps,DC=mydc,DC=xyz     # 可以理解为管理员账号(只读账号就可以), 根据自己实际情况填写
bindpw xxxx               # 上面账号的密码
ssl no
filter passwd (objectClass=user)        # 这里的话,根据自己的实际情况填写,其实我也不大懂,我是经过调试填的这个
map    passwd uid sAMAccountName        # 这里也是,配合上面fiter进行填写的,下面我会说一下 我是怎么调试的

(1) 没配置filtermap, 用正确的账号密码登录不了FTP

一开始我没有配置filtermap, 登录ftp,一直报账号密码错误,如下

# ftp localhost
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
220 Welcome to virtual FTP service.
Name (localhost:root): pcan1250
331 Please specify the password.
Password:
530 Login incorrect.
Login failed.
ftp> 

我知道自己的账号密码没错,问题肯定是映射问题,应该是vsftp是使用的账号与域控的映射不一致(也就是与我的预期不一致)引起的。 但是我看了操作系统日志,没有看到有相关的报错。问题一下子卡住了。

(2) 调试nslcd服务
既然从/var/log/secure 知道大概是用的nslcd服务去访问ldap的,那就看看能不能从这里入手。通过查看nslcd帮助,发现有个debug选项,可以试一下

# nslcd --help
Usage: nslcd [OPTION]...
Name Service LDAP connection daemon.
  -c, --check        check if the daemon already is running
  -d, --debug        don't fork and print debugging to stderr
      --help         display this help and exit
      --version      output version information and exit

Report bugs to <nss-pam-ldapd-users@lists.arthurdejong.org>

先停掉,然后用 -d 启动到调试模式

# systemctl stop nslcd.service 
# nslcd -d
nslcd: DEBUG: add_uri(ldap://XXX)           
nslcd: version 0.8.13 starting
nslcd: DEBUG: unlink() of /var/run/nslcd/socket failed (ignored): No such file or directory
nslcd: DEBUG: initgroups("nslcd",55) done
nslcd: DEBUG: setgid(55) done
nslcd: DEBUG: setuid(65) done
nslcd: accepting connections

很好, 有日志输出了, 再用ftp localhost访问一次看看, 可以看到有日志输出了

# nslcd -d
nslcd: DEBUG: add_uri(ldap://XXXX)
nslcd: version 0.8.13 starting
nslcd: DEBUG: unlink() of /var/run/nslcd/socket failed (ignored): No such file or directory
nslcd: DEBUG: initgroups("nslcd",55) done
nslcd: DEBUG: setgid(55) done
nslcd: DEBUG: setuid(65) done
nslcd: accepting connections
nslcd: [8b4567] DEBUG: connection from pid=321676 uid=0 gid=0
nslcd: [8b4567] <authc="pcan1250"> DEBUG: nslcd_pam_authc("pcan1250","vsftpd","***")
nslcd: DEBUG: accept() failed (ignored): Resource temporarily unavailable
nslcd: [8b4567] <authc="pcan1250"> DEBUG: myldap_search(base="DC=mydc,DC=xyz", filter="(&(objectClass=posixAccount)(uid=pcan1250))")
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_initialize(ldap://XXXX)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_rebind_proc()
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,0)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,0)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,0)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_simple_bind_s("CN=XXXX,OU=vApps,DC=mydc,DC=xyz","***") (uri="ldap://XXXX")
nslcd: [8b4567] <authc="pcan1250"> DEBUG: rebinding to ldap://DomainDnsZones.mydc.xyz/DC=DomainDnsZones,DC=mydc,DC=xyz
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_simple_bind_s("CN=XXXX,OU=vApps,DC=mydc,DC=xyz","***") (uri="ldap://DomainDnsZones.mydc.xyz/DC=DomainDnsZones,DC=mydc,DC=xyz")
nslcd: [8b4567] <authc="pcan1250"> DEBUG: rebinding to ldap://ForestDnsZones.mydc.xyz/DC=ForestDnsZones,DC=mydc,DC=xyz
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_simple_bind_s("CN=XXXX,OU=vApps,DC=mydc,DC=xyz","***") (uri="ldap://ForestDnsZones.mydc.xyz/DC=ForestDnsZones,DC=mydc,DC=xyz")
nslcd: [8b4567] <authc="pcan1250"> DEBUG: rebinding to ldap://mydc.xyz/CN=Configuration,DC=mydc,DC=xyz
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_simple_bind_s("CN=XXXX,OU=vApps,DC=mydc,DC=xyz","***") (uri="ldap://mydc.xyz/CN=Configuration,DC=mydc,DC=xyz")
nslcd: [8b4567] <authc="pcan1250"> DEBUG: ldap_result(): end of results (0 total)
nslcd: [8b4567] <authc="pcan1250"> DEBUG: "pcan1250": user not found: No such object

核心是这行 myldap_search(base="DC=mydc,DC=xyz", filter="(&(objectClass=posixAccount)(uid=pcan1250))"), 我之前用python去连接ldap的时候,有一定的经验,所以我知道是这个fiter的问题,我这边不是用的uid, 而是用sAMAccountName, 并且objectClass 也不对,因此我按照我的实际情况改成了如下

filter passwd (objectClass=user)     
map    passwd uid sAMAccountName     

整个/etc/nslcd.conf 文件内容如上(步骤3开头已经列出来)所示, 再次访问ftp

# ftp localhost
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
220 Welcome to virtual FTP service.
Name (localhost:root): pcan1250
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (127,0,0,1,13,225).
150 Here comes the directory listing.
-rw-r--r--    1 0        0               0 Sep 18 09:50 a

# ls -alrt /opt
total 4
dr-xr-xr-x. 21 root root 4096 Sep 18 09:50 ..
-rw-r--r--   1 root root    0 Sep 18 09:50 a
drwxr-xr-x   2 root root   15 Sep 18 09:50 .

可以看到,已经正常登录,用未授权的账号登录测试一下

# ftp localhost
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
220 Welcome to virtual FTP service.
Name (localhost:root): 11111111 
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (127,0,0,1,14,172).
150 Here comes the directory listing.
-rw-r--r--    1 0        0               0 Sep 18 15:29 当前没有权限访问该FTP.txt
226 Directory send OK.
ftp> 
ftp> quit
221 Goodbye.

# ls /home/anonymous/
当前没有权限访问该FTP.txt

正是访问到了/home/anonymous/ (上面vsftpd.conf配置的)下。 至此,VSFTP + LDAP已完成。

后续与总结

后续有新的用户要授权的话,由于都是同样的local_root, 因此,只需要用pcan1250文件做软链接就行,比如说,现在要加一个111111账号访问,只需要如下命令

# cd /etc/vsftpd/vusers
# ln -s  pcan1250 111111

后续可以写一个脚本,用来批量添加或者删除用户。

这里的核心是调试nslcd连接到LDAP Server, 如果没有debug信息,可以需要耗费很多时间去慢慢调整....

posted @ 2024-09-23 15:17  xuege  阅读(110)  评论(0编辑  收藏  举报