Linux搭建Samba服务器实现跨平台文件共享

 更新时间:2026年04月23日 09:13:02   作者:知远漫谈  
在当今多设备、多操作系统并存的办公与开发环境中,跨平台文件共享已成为刚需,无论是Windows用户需要访问Linux服务器上的项目源码,还是macOS用户希望同步设计素材,Samba都能提供稳定、高效、安全的解决方案,本文将从零开始,手把手教你如何在Linux系统上搭建Samba 服务器

引言

在当今多设备、多操作系统并存的办公与开发环境中,跨平台文件共享已成为刚需。无论是 Windows 用户需要访问 Linux 服务器上的项目源码,还是 macOS 用户希望同步设计素材,亦或是 Android/iOS 移动端临时获取配置文件——Samba 都能提供稳定、高效、安全的解决方案。

本文将从零开始,手把手教你如何在 Linux 系统上搭建 Samba 服务器,并通过 Java 编写客户端程序实现自动化文件上传下载,最后辅以网络拓扑图和权限流程图帮助理解整体架构。

什么是 Samba?

Samba 是一套开源软件套件,它实现了 SMB/CIFS 协议(Server Message Block / Common Internet File System),允许 Linux/Unix 系统与 Windows 系统之间无缝共享文件和打印机资源。

SMB 最初由 IBM 开发,后被微软广泛用于 Windows 文件共享系统。Samba 项目始于 1992 年,目标是让非 Windows 系统也能“说 SMB 的语言”。

Samba 的核心优势:

  • ✅ 跨平台兼容性极强:Windows、macOS、Linux、Android、iOS 均原生支持挂载
  • ✅ 支持用户认证、权限控制、加密传输
  • ✅ 可集成 Active Directory(企业级部署)
  • ✅ 支持软链接、硬链接、ACL、配额等高级功能
  • ✅ 社区活跃,文档丰富,长期维护

环境准备

我们以 Ubuntu 22.04 LTS 为例进行演示,其他发行版(如 CentOS、Debian、Fedora)操作类似,仅包管理器命令略有不同。

系统要求

  • Linux 服务器一台(物理机或虚拟机均可)
  • root 权限或 sudo 权限
  • 至少一个可访问的公网 IP 或局域网 IP
  • 防火墙开放 TCP 139 和 445 端口
  • Java 8+(用于后续客户端示例)

第一步:安装 Samba

打开终端,执行以下命令安装 Samba 服务:

sudo apt update
sudo apt install samba -y

安装完成后,验证版本:

smbd --version

输出类似:

Version 4.15.13-Ubuntu

第二步:创建共享目录

我们将在 /srv/samba/shared 创建一个共享目录:

sudo mkdir -p /srv/samba/shared
sudo chown nobody:nogroup /srv/samba/shared
sudo chmod 755 /srv/samba/shared

注意:nobody:nogroup 是默认匿名访问账户,生产环境建议使用特定用户组。

你也可以创建带用户权限的私有目录:

sudo mkdir -p /srv/samba/private
sudo groupadd smbgroup
sudo useradd -g smbgroup -s /sbin/nologin smbuser
sudo chown smbuser:smbgroup /srv/samba/private
sudo chmod 770 /srv/samba/private

第三步:配置 Samba

Samba 主配置文件位于 /etc/samba/smb.conf。备份原始配置:

sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

编辑配置文件:

sudo nano /etc/samba/smb.conf

在文件末尾追加如下内容:

[global]
   workgroup = WORKGROUP
   server string = Samba Server %v
   netbios name = ubuntu-samba
   security = user
   map to guest = bad user
   dns proxy = no
[shared]
   path = /srv/samba/shared
   browsable = yes
   writable = yes
   guest ok = yes
   read only = no
   create mask = 0755
   directory mask = 0755
[private]
   path = /srv/samba/private
   valid users = smbuser
   browsable = yes
   writable = yes
   guest ok = no
   read only = no
   create mask = 0644
   directory mask = 0755

参数说明:

参数名作用说明
workgroup工作组名称,默认为 WORKGROUP
security=user启用用户认证
map to guest无效用户映射为访客
browsable是否在“网络邻居”中显示
writable是否允许写入
guest ok是否允许匿名访问
valid users指定允许访问该共享的用户

第四步:添加 Samba 用户

即使系统已有用户,也需要为其设置 Samba 密码:

sudo smbpasswd -a smbuser

输入两次密码即可。

Samba 密码独立于系统密码,即使系统用户无登录 shell,也可正常使用 Samba。

启用用户:

sudo smbpasswd -e smbuser

第五步:重启服务 & 开机自启

sudo systemctl restart smbd nmbd
sudo systemctl enable smbd nmbd

检查状态:

sudo systemctl status smbd

应看到 active (running) 状态。

第六步:防火墙配置

Ubuntu 默认使用 ufw,开放 Samba 端口:

sudo ufw allow 139/tcp
sudo ufw allow 445/tcp
sudo ufw reload

验证端口监听:

sudo ss -tulnp | grep smbd

应看到类似:

tcp   LISTEN 0      50           *:139       *:*    users:(("smbd",pid=1234,fd=32))
tcp   LISTEN 0      50           *:445       *:*    users:(("smbd",pid=1234,fd=33))

第七步:客户端连接测试

Windows 客户端

打开“文件资源管理器”,地址栏输入:

\\<服务器IP>\

例如:

\\192.168.1.100\

应能看到 sharedprivate 两个共享目录。

双击 private,会提示输入用户名密码 → 输入 smbuser 及其密码即可访问。

macOS 客户端

Finder → “前往” → “连接服务器” → 输入:

smb://192.168.1.100

点击“连接”,选择“注册用户”,输入凭据。

Linux 客户端挂载

安装 cifs-utils:

sudo apt install cifs-utils -y

创建挂载点:

sudo mkdir /mnt/samba-private

挂载:

sudo mount -t cifs //192.168.1.100/private /mnt/samba-private -o username=smbuser,password=yourpassword,uid=$(id -u),gid=$(id -g)

网络架构图(mermaid)

下面这张图展示了典型的 Samba 服务器在网络中的位置及其与各类客户端的关系:

第八步:编写 Java 客户端程序(JCIFS)

虽然现代 Java 推荐使用 SMBJ(支持 SMB2/3),但为了兼容性和教学目的,我们先使用 JCIFS(仅支持 SMB1,适合内网测试)。

注意:SMB1 存在安全风险,不建议在公网使用。生产环境请升级至 SMBJ。

Maven 依赖

pom.xml 中添加:

<dependency>
    <groupId>jcifs</groupId>
    <artifactId>jcifs</artifactId>
    <version>1.3.17</version>
</dependency>

 JCIFS 官方主页:http://jcifs.samba.org/

示例代码:上传文件到 Samba

import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class SambaUploader {
    private static final String SMB_URL = "smb://smbuser:yourpassword@192.168.1.100/private/";
    private static final String LOCAL_FILE_PATH = "/home/user/test.txt";
    public static void main(String[] args) {
        try {
            uploadFile();
            System.out.println("✅ 文件上传成功!");
        } catch (IOException e) {
            System.err.println("❌ 上传失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
    public static void uploadFile() throws IOException {
        SmbFile remoteDir = new SmbFile(SMB_URL);
        if (!remoteDir.exists()) {
            remoteDir.mkdirs();
        }
        SmbFile remoteFile = new SmbFile(SMB_URL + "uploaded_test.txt");
        try (FileInputStream fis = new FileInputStream(LOCAL_FILE_PATH);
             SmbFileOutputStream sfos = new SmbFileOutputStream(remoteFile)) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                sfos.write(buffer, 0, bytesRead);
            }
        }
    }
}

示例代码:从 Samba 下载文件

import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class SambaDownloader {
    private static final String SMB_URL = "smb://smbuser:yourpassword@192.168.1.100/private/uploaded_test.txt";
    private static final String LOCAL_SAVE_PATH = "/home/user/downloaded_test.txt";
    public static void main(String[] args) {
        try {
            downloadFile();
            System.out.println("✅ 文件下载成功!");
        } catch (IOException e) {
            System.err.println("❌ 下载失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
    public static void downloadFile() throws IOException {
        SmbFile remoteFile = new SmbFile(SMB_URL);
        if (!remoteFile.exists()) {
            throw new IOException("远程文件不存在:" + SMB_URL);
        }
        try (SmbFileInputStream sfis = new SmbFileInputStream(remoteFile);
             FileOutputStream fos = new FileOutputStream(LOCAL_SAVE_PATH)) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = sfis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }
    }
}

示例代码:列出目录内容

import jcifs.smb.SmbFile;
import java.io.IOException;
public class SambaLister {
    private static final String SMB_DIR_URL = "smb://smbuser:yourpassword@192.168.1.100/private/";
    public static void main(String[] args) {
        try {
            listDirectory();
        } catch (IOException e) {
            System.err.println("❌ 列出目录失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
    public static void listDirectory() throws IOException {
        SmbFile dir = new SmbFile(SMB_DIR_URL);
        if (!dir.exists() || !dir.isDirectory()) {
            System.out.println("⚠️ 目录不存在或不是目录:" + SMB_DIR_URL);
            return;
        }
        SmbFile[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            System.out.println("📂 目录为空");
            return;
        }
        System.out.println("📁 目录内容:");
        for (SmbFile file : files) {
            String type = file.isDirectory() ? "[DIR]" : "[FILE]";
            System.out.printf("%s %s (大小: %d 字节)%n", type, file.getName(), file.length());
        }
    }
}

权限控制流程图(mermaid)

Samba 的权限控制涉及多个层级,下图展示用户访问文件时的权限校验流程:

高级配置技巧

1. 启用回收站功能(防止误删)

在共享段落中添加:

vfs objects = recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch = yes
recycle:maxsize = 0

这样删除的文件会被移到 .recycle/用户名/ 目录下。

2. 限制访问 IP(增强安全)

[global] 或具体共享段中添加:

hosts allow = 192.168.1.0/24 10.0.0.5
hosts deny = ALL

只允许指定网段或 IP 访问。

3. 日志级别调整

调试阶段可开启详细日志:

log level = 2
log file = /var/log/samba/%m.log
max log size = 50

日志按客户端主机名 %m 分割,便于排查问题。

4. 使用符号链接

若需支持软链接,添加:

follow symlinks = yes
wide links = yes
unix extensions = no

wide links 允许跨文件系统链接,存在安全风险,请谨慎启用。

安全加固建议

禁用 SMB1(除非必要)
[global] 中添加:

server min protocol = SMB2

强制加密传输(适用于公网)

server smb encrypt = required

定期轮换密码

sudo smbpasswd -a smbuser  # 重新设置密码

最小权限原则
不要给共享目录 777 权限,按需分配。

监控异常登录

sudo tail -f /var/log/samba/log.*

性能优化

1. 调整 socket 缓冲区

socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536

2. 启用缓存

read raw = yes
write raw = yes
oplocks = yes
max xmit = 65535

3. 限制并发连接数(防 DoS)

max connections = 50

监控与日志分析

Samba 日志默认位于 /var/log/samba/,可通过脚本定时分析:

#!/bin/bash
LOG_DIR="/var/log/samba"
grep "ACCESS DENIED" $LOG_DIR/*.log | wc -l
grep "NT_STATUS_WRONG_PASSWORD" $LOG_DIR/*.log | wc -l

你也可以集成到 Prometheus + Grafana 进行可视化监控。

🌐 Grafana 官网:https://grafana.com/
🌐 Prometheus 官网:https://prometheus.io/

自动化脚本示例(Bash + Java)

你可以编写一个 Bash 脚本,在每天凌晨自动上传备份文件:

#!/bin/bash
# backup_to_samba.sh

DATE=$(date +%Y%m%d)
BACKUP_FILE="/backup/app_backup_$DATE.tar.gz"

# 生成备份
tar -czf $BACKUP_FILE /var/www/html /etc/nginx

# 调用 Java 上传程序
java -cp ".:lib/*" SambaUploader $BACKUP_FILE

# 清理本地 7 天前备份
find /backup -name "*.tar.gz" -mtime +7 -delete

echo "✅ $BACKUP_FILE 已上传至 Samba 服务器"

配合 crontab:

0 2 * * * /home/scripts/backup_to_samba.sh >> /var/log/backup.log 2>&1

常见问题解答(FAQ)

Q1:连接时报错 “NT_STATUS_ACCESS_DENIED”

  • 检查用户名密码是否正确
  • 检查 valid users 是否包含该用户
  • 检查 Linux 文件系统权限:ls -l /srv/samba/private

Q2:Windows 提示 “找不到网络路径”

  • 检查防火墙是否放行 445 端口
  • 检查 Samba 服务是否运行:systemctl status smbd
  • 尝试关闭 Windows 防火墙临时测试

Q3:Java JCIFS 报错 “Failed to connect: 0.0.0.0<00>/192.168.1.100”

  • 确保 URL 格式正确:smb://user:pass@ip/share/
  • 确保网络可达,尝试 ping 或 telnet 445
  • 若使用域名,确保 DNS 解析正常

Q4:能否实现匿名上传?

可以,但极度不安全!仅限内网测试:

[anon_upload]
   path = /srv/samba/anon
   writable = yes
   guest ok = yes
   read only = no
   create mask = 0666
   directory mask = 0777

并确保目录权限:

chmod 777 /srv/samba/anon

测试你的 Samba 服务

你可以使用 smbclient 命令行工具测试:

smbclient //192.168.1.100/private -U smbuser

输入密码后,进入交互式界面:

smb: \> ls
smb: \> put localfile.txt remotefile.txt
smb: \> get remotefile.txt downloaded.txt
smb: \> exit

Java SMBJ 替代方案(推荐生产使用)

由于 JCIFS 仅支持 SMB1,强烈建议新项目使用 SMBJ,支持 SMB2/3,更安全高效。

Maven 依赖:

<dependency>
    <groupId>com.hierynomus</groupId>
    <artifactId>smbj</artifactId>
    <version>0.11.5</version>
</dependency>

简单上传示例:

import com.hierynomus.mssmb2.SMB2Packet;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import java.io.File;
import java.nio.file.Files;
public class SmbjUploader {
    public static void main(String[] args) throws Exception {
        SMBClient client = new SMBClient();
        try (Connection connection = client.connect("192.168.1.100")) {
            AuthenticationContext ac = new AuthenticationContext("smbuser", "password".toCharArray(), "");
            Session session = connection.authenticate(ac);
            try (DiskShare share = (DiskShare) session.connectShare("private")) {
                File localFile = new File("/path/to/local/file.txt");
                share.upload(localFile, "remote_file.txt", Files.readAllBytes(localFile.toPath()));
                System.out.println("✅ 上传成功(SMBJ)");
            }
        }
    }
}

SMBJ GitHub 页面(仅参考结构,不提供地址)→ 搜索 “hierynomus smbj”

企业级应用场景

场景一:CI/CD 自动部署

  • Jenkins 构建产物 → 通过 Java 程序上传至 Samba → 运维挂载后部署

场景二:多部门文件协作

  • 财务部上传报表 → 市场部直接访问 → 无需 FTP/U盘传递

场景三:移动端素材同步

  • 设计师用 iPad 保存 PSD → 自动同步至 Samba → 开发取用切图

场景四:日志集中收集

  • 多台服务器每日压缩日志 → Java 定时上传 → 统一归档分析

总结

通过本文,你已掌握:

✅ Linux 上完整搭建 Samba 服务器
✅ 配置匿名/认证共享目录
✅ Windows/macOS/Linux 客户端连接方法
✅ Java JCIFS/SMBJ 客户端编程实现自动化
✅ 安全加固与性能调优技巧
✅ 企业级应用场景设计

Samba 作为老牌且稳定的跨平台文件共享方案,依然在现代 IT 架构中扮演重要角色。无论是小型工作室还是大型企业,都能从中受益。

附加:一键安装脚本(供参考)

#!/bin/bash
# install_samba.sh

echo "🐧 正在安装 Samba..."
sudo apt update && sudo apt install samba -y

echo "📁 创建共享目录..."
sudo mkdir -p /srv/samba/{shared,private}
sudo chmod 755 /srv/samba/shared
sudo chmod 770 /srv/samba/private

echo "📝 写入配置文件..."
cat << EOF | sudo tee /etc/samba/smb.conf > /dev/null
[global]
   workgroup = WORKGROUP
   server string = Samba Server %v
   security = user
   map to guest = bad user
   dns proxy = no

[shared]
   path = /srv/samba/shared
   browsable = yes
   writable = yes
   guest ok = yes
   read only = no

[private]
   path = /srv/samba/private
   valid users = smbuser
   browsable = yes
   writable = yes
   guest ok = no
   read only = no
EOF

echo "🔐 添加 Samba 用户 smbuser(密码设为 123456)..."
sudo useradd -M -s /sbin/nologin smbuser
echo -e "123456\n123456" | sudo smbpasswd -a -s smbuser
sudo smbpasswd -e smbuser

echo "🔁 重启服务..."
sudo systemctl restart smbd nmbd
sudo systemctl enable smbd nmbd

echo "🔥 开放防火墙..."
sudo ufw allow 139,445/tcp

echo "🎉 安装完成!服务器 IP:$(hostname -I | awk '{print $1}')"
echo "👉 Windows 访问:\\\\$(hostname -I | awk '{print $1}')"

保存为 install_samba.sh,赋予执行权限:

chmod +x install_samba.sh
./install_samba.sh

结语

文件共享不应成为跨平台协作的障碍。Samba 以其成熟稳定、配置灵活、生态完善的特点,依然是解决这一问题的最佳选择之一。结合 Java 自动化能力,更能释放其在 DevOps、数据同步、备份归档等场景下的巨大潜力。

以上就是Linux搭建Samba服务器实现跨平台文件共享的详细内容,更多关于Linux搭建Samba跨平台文件共享的资料请关注脚本之家其它相关文章!

相关文章

  • APACHE 自定义404错误页面设置方法

    APACHE 自定义404错误页面设置方法

    自定义404页面返回不当状态码如200等给网站最终SEO效果带来的不利影响,因此,确保自定义的404错误页面能够返回404状态码是极为重要的,也是网站优化与SEO的基本要求
    2017-03-03
  • Linux使用tcpdump捕获网络数据包的详细步骤

    Linux使用tcpdump捕获网络数据包的详细步骤

    在网络故障排查、协议分析或网络安全检测中,抓包工具是不可或缺的"利器",而tcpdump作为Linux系统中历史最悠久、功能最强大的命令行抓包工具,至今仍是工程师的首选,本文将从基础操作到实战技巧,带你掌握用tcpdump捕获网络数据包的完整流程,需要的朋友可以参考下
    2025-08-08
  • Linux使用Cron+AT实现在某个确定的时间段内随机执行命令

    Linux使用Cron+AT实现在某个确定的时间段内随机执行命令

    写了个脚本签到,但是不想总是在确定的时间签到,不然在数据库里面的记录太假了,所以需要在确定的时间段内,随机选个时间执行,最后想到了使用Cron+AT实现,需要的朋友可以参考下
    2016-07-07
  • Linux下自动删除归档日志文件的方法

    Linux下自动删除归档日志文件的方法

    这篇文章主要介绍了Linux下自动删除归档日志文件的方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2016-12-12
  • Apache负载均衡设置方法 mod_proxy使用介绍

    Apache负载均衡设置方法 mod_proxy使用介绍

    本文主要讲解了Apache负载均衡功能的代码配置,首先我们通过几个模块的功能进行配置,之后就会发现其中的奥秘了,那么我们还是来具体看文章吧
    2012-10-10
  • Apache Ranger简介及部署示例

    Apache Ranger简介及部署示例

    Apache Ranger 是一个集中式安全管理框架,专为 Hadoop 生态系统设计,它提供统一的策略管理、细粒度访问控制和实时审计功能,支持主流大数据组件如 HDFS、Hive、HBase、Kafka 等,本文给大家介绍Apache Ranger简介及部署示例,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • Linux卸载自带jdk并安装新jdk版本的图文教程

    Linux卸载自带jdk并安装新jdk版本的图文教程

    在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK 1.8,所以本文给大家详细介绍了Linux卸载自带jdk并安装新jdk版本的图文教程,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2025-04-04
  • 关闭Apache的目录浏览功能的方法

    关闭Apache的目录浏览功能的方法

    这篇文章主要介绍了如何关闭Apache的目录浏览功能,需要的朋友可以参考下
    2014-02-02
  • 解决Ubuntu“无法定位软件包 xxx”的问题及分析

    解决Ubuntu“无法定位软件包 xxx”的问题及分析

    本文介绍了在配置Ubuntu系统时遇到软件源问题的解决方法,包括安装vim、备份软件源配置文件、修改软件源配置文件和重新获取软件源列表
    2025-12-12
  • 改造ctrl+alt+del(默认重启)为一个信息搜集脚本的脚本

    改造ctrl+alt+del(默认重启)为一个信息搜集脚本的脚本

    远程一个服务器总是出现网络故障,因为不方便让IDC工程师做太详细的操作,每次都是让他按ctrl+alt+del重启服务器,最后写了这么一个脚本,实现的效果是
    2011-05-05

最新评论