通过用户+VPN IP地址对来限制Samba4身份验证

通过用户+VPN IP地址对来限制Samba4身份验证

我们正在努力在办公室内实现零信任安全模型,服务器由 WireGuard VPN 保护。我们已经使用 WireGuard 进行远程访问,因此这是确保所有网络流量加密的最简单方法。WireGuard 为每个用户保证一个特定的 IP 地址。

我们希望使用用户名和 IP 地址来验证文件服务器的访问权限,以防止在发生入侵时发生横向移动。我们使用 Samba 4.13 和简单的默认设置passdb backend = tdbsam(无域控制器)。

我希望使用 PAM 来提供一个简单的解决方案,但尽管默认配置文件仍然包含auth,但我读到它不受支持(Samba 使用质询-响应身份验证,这不是 PAM 方式)。当我添加auth required pam_rhosts.so到时/etc/pam.d/samba,我的身份验证能力没有任何变化。将其添加到accountsession部分会导致身份验证失败,即使是从授权 IP 地址。

我能想到的其他解决方案是修改源代码或运行 Active Directory 域控制器,但这些似乎是一项更大的实施和维护工作。应用程序防火墙可能也有效,但我不知道有什么可以检查 Samba 流量。

有没有简单的方法可以将此用户-主机对限制(或一般的 MFA)添加到 Samba 4?

- 编辑 -

/etc/pam.d/samba配置显然有一定的效果,因为在该部分的任何行中添加“调试”选项auth都会提供如下调试日志记录,尽管额外的required行不会对身份验证的结果产生影响:

[2022/11/10 15:56:56.258835,  3] ../../auth/ntlmssp/ntlmssp_server.c:509(ntlmssp_server_preauth)
  Got user=[username] domain=[FILESERVER] workstation=[COMPUTER-NAME] len1=24 len2=190
[2022/11/10 15:56:56.258932,  3] ../../source3/auth/auth.c:200(auth_check_ntlm_password)
  check_ntlm_password:  Checking password for unmapped user [FILESERVER]\[username]@[COMPUTER-NAME] with the new password interface
[2022/11/10 15:56:56.258959,  3] ../../source3/auth/auth.c:203(auth_check_ntlm_password)
  check_ntlm_password:  mapped user is: [FILESERVER]\[username]@[COMPUTER-NAME]
[2022/11/10 15:56:56.259651,  4] ../../source3/auth/check_samsec.c:183(sam_account_ok)
  sam_account_ok: Checking SMB password for user username
[2022/11/10 15:56:56.262124,  3] ../../source3/auth/auth.c:267(auth_check_ntlm_password)
  auth_check_ntlm_password: sam_ignoredomain authentication for user [username] succeeded
[2022/11/10 15:56:56.262230,  4] ../../source3/auth/pampass.c:485(smb_pam_start)
  smb_pam_start: PAM: Init user: username
[2022/11/10 15:56:56.267184,  4] ../../source3/auth/pampass.c:494(smb_pam_start)
  smb_pam_start: PAM: setting rhost to: 10.1.2.3
[2022/11/10 15:56:56.267246,  4] ../../source3/auth/pampass.c:503(smb_pam_start)
  smb_pam_start: PAM: setting tty
[2022/11/10 15:56:56.267285,  4] ../../source3/auth/pampass.c:511(smb_pam_start)
  smb_pam_start: PAM: Init passed for user: username
[2022/11/10 15:56:56.267323,  4] ../../source3/auth/pampass.c:569(smb_pam_account)
  smb_pam_account: PAM: Account Management for User: username
[2022/11/10 15:56:56.267907,  4] ../../source3/auth/pampass.c:588(smb_pam_account)
  smb_pam_account: PAM: Account OK for User: username
[2022/11/10 15:56:56.268550,  4] ../../source3/auth/pampass.c:467(smb_pam_end)
  smb_pam_end: PAM: PAM_END OK.
[2022/11/10 15:56:56.268641,  2] ../../source3/auth/auth.c:323(auth_check_ntlm_password)
  check_ntlm_password:  authentication for user [username] -> [username] -> [username] succeeded

答案1

我对这个特定主题不太热衷,但添加后auth required pam_rhosts.so,您确实创建了相应的~/.rhosts文件,对吗?

此链接说 rhosts 文件需要指定hostname [username]允许的对,我假设 ip 地址可以代替主机名同样有效。

您是否可以分享一些特定的日志消息(当然,如果需要的话,可以删除),以便提供更多见解?


编辑- 不知道这是否会起作用,但你可以尝试网络组

我不确定设置这些的要求或程序,或者是否像创建和填充文件一样简单/etc/netgroup

然后根据手册页中的示例成功时,似乎您可以为(主机,用户)对创建网络组,我想象它看起来像这样:

sambang (alicepc, alice) (bobpc, bob) (charliepc, charlie)

并将此模块添加到您的 samba 身份验证,以使 pam 身份验证在 (主机,用户) 对位于网络组中时成功,例如:

auth required pam_succeed_if.so audit user innetgr netgroup sambang

我可能会更换审计调试直到它能够工作(假设它可以工作)。

答案2

Samba 的每个 IP/子网文件的 ACL 是否/etc/hosts.allow足以/etc/hosts.deny限制用户的共享挂载?

本文介绍如何设置 samba 的授权

编辑:另外,这里是针对漫游主文件夹的 PAM 模块的答案。也许它与您的用例相同?

FWIW,我会尝试一下Hashicorp 的边界寻求 0 信任解决方案。

答案3

我决定使用 来监控用户会话smbstatus。这不会在登录时立即发生,因此它不会阻止某人登录,但它会在几秒钟内终止无效会话。这不是一个完美的解决方案,但在我们的例子中应该足够了。

以下是我在 PHP 中实现的方法:

#!/usr/bin/php
<?php
/**
@file blockInvalidSambaUserHosts.php
Block invalid user-host pairs from using Samba.
Run as a root service.
Configure valid pairs in /etc/samba/validUserHosts.conf with lines like:
alice 10.1.0.100
bob 10.1.0.101,10.2.0.88
**/

$STATUS_COMMAND = <<< 'END'
smbstatus -p | awk '/SMB3/{print $1" "$2" "$4}'
END;

$configFile = '/etc/samba/validUserHosts.conf';
if (!file_exists($configFile)) file_put_contents($configFile,'');

list($configTime,$validUserHosts) = getConfig($configFile);

while (true) {
    $connections = explode("\n",trim(shell_exec($STATUS_COMMAND)));
    foreach ($connections as $c) {
        if (!$c) continue;
        list($pid,$uname,$ip) = explode(' ',$c);

        if (!isset($validUserHosts[$uname])) $msg = "Invalid user $uname.";
        elseif (!in_array($ip,$validUserHosts[$uname])) $msg = "Invalid address $ip for user $uname.";
        else continue;

        error_log($msg);
        killProcess($ip);
        blockIPAddress($ip,$uname);
        //notify($ip,$uname);
    }

    sleep(10);

    // Reload config if it has been modified
    if (filemtime($configFile) > $configTime) {
        list($configTime,$validUserHosts) = getConfig($configFile);
    }
}

// Immediately stop any operations in progress
function killProcess(string $ip): void {
    shell_exec("kill -9 $ip");
    error_log("Killed smbd process for $ip.");
}

// Immediately block further traffic
function blockIPAddress(string $ip, string $uname): void {
    shell_exec("iptables -I INPUT -s $ip -j DROP -m comment --comment '$uname@$ip not valid for Samba'");
    error_log("All traffic from $ip is now blocked.");
}

function getConfig($configFile) {
    $utime = filemtime($configFile);
    $lines = file($configFile);
    $validUserHosts = [];
    foreach ($lines as $line) {
        list($uname,$hosts) = explode(' ',rtrim($line));
        $validUserHosts[$uname] = explode(',',$hosts);
    }

    return [$utime,$validUserHosts];
}

使用如下的 systemd 配置:

# @file blockInvalidSambaUserHosts.service
# @version 1.0.0
[Unit]
Description=Block invalid user-host pairs from using Samba
After=smbd.service

[Service]
Type=simple
ExecStart=/root/blockInvalidSambaUserHosts.php
StandardOutput=append:/var/log/sambaUserHostBlocks.log
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

相关内容