SSHFS(SSH Filesystem)是一个基于FUSE的文件系统客户端,允许您通过SSH协议挂载远程服务器的目录到本地文件系统。它使用SFTP协议进行文件传输,提供了安全、便捷的远程文件访问方式。
通过SSH加密所有数据传输,安全性高
无需在远程服务器安装额外服务
保持远程文件权限和属性
文件修改实时同步到远程服务器
像访问本地文件一样访问远程文件
支持多种挂载选项和参数调优
# 安装sshfs和fuse
sudo apt update
sudo apt install sshfs fuse
# 将用户添加到fuse组(首次使用需要)
sudo usermod -a -G fuse $USER
# 重新登录使组生效
# 或执行:newgrp fuse
# 安装EPEL源和sshfs
sudo yum install epel-release
sudo yum install fuse-sshfs
# 对于RHEL 8/CentOS 8
sudo dnf install epel-release
sudo dnf install fuse-sshfs
# 加载fuse内核模块
sudo modprobe fuse
sudo dnf install fuse-sshfs
# 通过Homebrew安装
brew install macfuse
brew install sshfs
# 安装后需要授权FUSE扩展
# 系统偏好设置 → 安全性与隐私 → 通用
SSHFS基于FUSE(Filesystem in Userspace)实现,允许非特权用户在用户空间创建自己的文件系统,而无需修改内核代码。
# 检查FUSE是否已安装
lsmod | grep fuse
# 或
modinfo fuse
# 如果未加载,手动加载
sudo modprobe fuse
# 检查当前用户是否在fuse组中
groups | grep fuse
sshfs [用户@]主机:[目录] 挂载点 [选项]
sshfs 远程路径 本地挂载点 [选项]
-p 2222
-C
-o allow_other
-f
-d
-s
| 选项 | 描述 | 默认值 |
|---|---|---|
allow_other |
允许其他用户访问挂载点 | 否 |
default_permissions |
让内核检查权限(推荐) | 否 |
uid=UID |
设置文件所有者的用户ID | 当前用户 |
gid=GID |
设置文件所有者的组ID | 当前组 |
reconnect |
自动重新连接断开连接 | 否 |
delay_connect |
延迟连接直到需要时 | 否 |
ServerAliveInterval=N |
SSH保活间隔(秒) | 0 |
compression=no |
禁用压缩 | 否 |
follow_symlinks |
跟随符号链接 | 是 |
cache=yes/no |
启用/禁用缓存 | 是 |
workaround=选项 |
特定服务器的问题解决方法 | - |
idmap=user |
用户ID映射方式 | none |
使用用户名密码挂载远程目录:
# 创建本地挂载点
mkdir ~/remote_server
# 挂载远程目录(会提示输入密码)
sshfs username@server.example.com:/home/username ~/remote_server
# 使用特定端口
sshfs -p 2222 username@server.example.com:/remote/path ~/local_mount
# 挂载后验证
df -h | grep sshfs
ls ~/remote_server
使用SSH密钥文件挂载(无需密码):
# 使用SSH配置文件中的主机
sshfs myserver:/var/www ~/www_mount
# 使用指定密钥文件
sshfs -o IdentityFile=~/.ssh/id_rsa user@host:/path ~/mount
# ~/.ssh/config 配置示例
Host myserver
HostName server.example.com
User username
Port 2222
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
ServerAliveCountMax 3
允许其他用户访问挂载点:
# 允许其他用户访问(需要/etc/fuse.conf中的user_allow_other)
sudo vim /etc/fuse.conf # 取消注释 user_allow_other
# 挂载时允许其他用户访问
sshfs -o allow_other,default_permissions user@host:/path /mnt/shared
# 设置特定用户/组权限
sshfs -o uid=1000,gid=1000 user@host:/path ~/mount
# 重新挂载以更改选项
sudo umount /mnt/shared
sudo sshfs -o allow_other,uid=1000,gid=1000 user@host:/path /mnt/shared
# 正常卸载
fusermount -u ~/remote_server
# 或
umount ~/remote_server
# 强制卸载(如果设备忙)
sudo umount -f ~/remote_server
# 或
fusermount -uz ~/remote_server
# 延迟卸载(等待设备不再忙)
sudo umount -l ~/remote_server
# 查看所有sshfs挂载点
mount | grep sshfs
df -h | grep fuse
# 批量卸载所有sshfs挂载
for mount in $(mount | grep sshfs | awk '{print $3}'); do
fusermount -u $mount
done
通过/etc/fstab配置自动挂载:
# 编辑/etc/fstab文件
sudo vim /etc/fstab
# 添加以下行(使用sshfs#前缀)
sshfs#username@server.example.com:/remote/path /local/mount fuse.sshfs defaults,allow_other,_netdev,reconnect 0 0
# 使用密钥认证的配置
sshfs#user@host:/path /mnt/remote fuse.sshfs IdentityFile=/home/user/.ssh/id_rsa,defaults,_netdev 0 0
# 测试fstab配置
sudo mount -a
# 如果使用密码认证,需要配置ssh密钥或使用ssh-agent
# 使用autofs自动挂载(按需挂载)
# 安装autofs
sudo apt install autofs
# 配置/etc/auto.master
sudo vim /etc/auto.master
# 添加:/mnt/sshfs /etc/auto.sshfs --timeout=300
# 创建auto.sshfs配置文件
sudo vim /etc/auto.sshfs
# 添加:webserver -fstype=fuse,rw,nodev,nonempty,allow_other :sshfs\#user@webserver\:/var/www/html
# 重启autofs服务
sudo systemctl restart autofs
# 访问时自动挂载
ls /mnt/sshfs/webserver
# 启用压缩(适合文本文件,不适合已压缩文件)
sshfs -C user@host:/path ~/mount
# 增大缓存大小
sshfs -o cache=yes,cache_timeout=3600,cache_stat_timeout=3600 user@host:/path ~/mount
# 禁用属性缓存
sshfs -o cache=no user@host:/path ~/mount
# 优化内核参数
sudo sysctl -w net.core.rmem_max=1048576
sudo sysctl -w net.core.wmem_max=1048576
sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 4194304"
sudo sysctl -w net.ipv4.tcp_wmem="4096 16384 4194304"
# 最佳性能挂载选项
sshfs -o Compression=no,cache=yes,large_read,kernel_cache,auto_cache \
user@host:/path ~/mount
# 针对大文件传输优化
sshfs -o Ciphers=aes128-ctr,Compression=no,cache=no,big_writes \
user@host:/path ~/mount
#!/bin/bash
# mount_servers.sh - 挂载多个服务器
# 服务器列表数组
servers=(
"web:/var/www/html"
"db:/var/lib/mysql"
"backup:/backup"
"data:/data"
)
# 挂载目录
mkdir -p ~/remote_mounts
for server_info in "${servers[@]}"; do
IFS=':' read -r server_name remote_path <<< "$server_info"
mount_point="$HOME/remote_mounts/$server_name"
# 创建挂载点目录
mkdir -p "$mount_point"
# 挂载远程目录
if sshfs "$server_name:$remote_path" "$mount_point"; then
echo "✓ $server_name 挂载成功: $mount_point"
else
echo "✗ $server_name 挂载失败"
fi
done
echo "所有挂载完成!"
df -h | grep sshfs
#!/bin/bash
# sshfs_manager.sh - SSHFS挂载管理脚本
CONFIG_FILE="$HOME/.sshfs_config"
MOUNT_BASE="$HOME/remote_mounts"
# 配置文件格式: 名称|主机|远程路径|端口|选项
# 示例: web|user@webserver|/var/www|22|-C -o allow_other
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
cat "$CONFIG_FILE"
else
echo "# SSHFS配置" > "$CONFIG_FILE"
echo "# 格式: 名称|主机|远程路径|端口|选项" >> "$CONFIG_FILE"
cat "$CONFIG_FILE"
fi
}
mount_all() {
load_config | grep -v '^#' | while IFS='|' read -r name host path port options; do
if [[ -n "$name" && -n "$host" && -n "$path" ]]; then
mount_point="$MOUNT_BASE/$name"
mkdir -p "$mount_point"
cmd="sshfs $host:$path $mount_point"
[[ -n "$port" ]] && cmd="$cmd -p $port"
[[ -n "$options" ]] && cmd="$cmd $options"
echo "挂载: $name"
eval "$cmd"
fi
done
}
umount_all() {
for mount in $(mount | grep sshfs | awk '{print $3}'); do
echo "卸载: $mount"
fusermount -u "$mount"
done
}
status() {
echo "当前SSHFS挂载状态:"
echo "====================="
mount | grep sshfs || echo "没有活动的SSHFS挂载"
echo ""
echo "配置的挂载点:"
ls -la "$MOUNT_BASE" 2>/dev/null || echo "挂载目录不存在"
}
case "$1" in
mount) mount_all ;;
umount|unmount) umount_all ;;
status) status ;;
*) echo "用法: $0 {mount|umount|status}" ;;
esac
# 1. 权限被拒绝错误
# 错误: fuse: failed to open /dev/fuse: Permission denied
# 解决方案:
sudo usermod -a -G fuse $USER
# 重新登录或执行: newgrp fuse
# 2. 挂载点不存在
# 错误: mountpoint not found
# 解决方案:
mkdir -p ~/remote_mount
sshfs user@host:/path ~/remote_mount
# 3. 连接超时
# 错误: Connection reset by peer
# 解决方案:
sshfs -o ServerAliveInterval=15,ServerAliveCountMax=3 user@host:/path ~/mount
# 或在 ~/.ssh/config 中添加:
ServerAliveInterval 30
ServerAliveCountMax 3
# 4. 只读文件系统
# 错误: Read-only file system
# 解决方案:
# 检查远程目录权限
# 使用-o rw选项重新挂载
sshfs -o rw user@host:/path ~/mount
# 5. 设备忙无法卸载
# 错误: device is busy
# 解决方案:
# 查找占用进程
sudo lsof +D ~/remote_mount
# 或强制卸载
fusermount -uz ~/remote_mount
# 6. 缓存问题
# 文件已删除但本地仍显示
# 解决方案:
# 禁用缓存或缩短缓存时间
sshfs -o cache=no user@host:/path ~/mount
# 或手动刷新
echo 3 | sudo tee /proc/sys/vm/drop_caches
# 启用详细调试
sshfs -d -f user@host:/path ~/mount 2>&1 | tee sshfs_debug.log
# 启用FUSE调试
sshfs -o debug user@host:/path ~/mount
# 查看系统日志
sudo dmesg | tail -50
sudo journalctl -f
# 检查网络连接
ssh -v user@host # 测试SSH连接
ssh -T user@host # 测试SSH连接(不执行命令)
# 测试SFTP子系统
sftp user@host
# 连接后执行: ls /
# 检查服务器配置
# 确保服务器sshd_config包含:
Subsystem sftp internal-sftp
| 特性对比 | SSHFS | NFS | Samba/CIFS |
|---|---|---|---|
| 安全性 | 高(SSH加密) | 中(可选加密) | 中(需要配置) |
| 配置复杂度 | 简单(只需SSH) | 复杂(需配置服务端) | 中等 |
| 跨平台 | 优秀(SSH普遍支持) | 良好(Unix为主) | 优秀(Windows原生) |
| 性能 | 中等(SSH开销) | 高(内核级) | 中等 |
| 身份验证 | SSH密钥/密码 | IP/主机名/Kerberos | 用户名/密码 |
| 适用场景 | 临时访问、安全传输、个人使用 | 局域网高速共享、服务器集群 | Windows共享、跨平台文件共享 |
# 挂载远程开发环境
sshfs devuser@devserver:/projects ~/projects
# 在本地IDE中编辑远程文件
code ~/projects/webapp
# 实时编译测试
cd ~/projects/webapp
make && make test
# 挂载数据库备份目录
sshfs dba@dbserver:/backup/mysql ~/db_backups
# 本地访问远程备份
ls -lh ~/db_backups
# 恢复到本地测试数据库
mysql -u root -p testdb < ~/db_backups/latest.sql
# 挂载云存储服务器
sshfs storage@cloud:/data ~/cloud_data
# 使用rsync同步文件
rsync -av ~/important_files/ ~/cloud_data/backup/
# 直接在挂载点操作
cp ~/documents/*.pdf ~/cloud_data/shared/
# 挂载多台服务器日志
sshfs root@webserver:/var/log ~/logs/webserver
sshfs root@dbserver:/var/log ~/logs/dbserver
# 统一查看日志
tail -f ~/logs/webserver/error.log
tail -f ~/logs/dbserver/mysql.log
# 备份配置文件
cp ~/logs/webserver/apache2.conf ~/backup/
command选项限制命令allow_other除非必要,并确保/etc/fuse.conf配置正确~/.ssh/config简化连接配置-C压缩选项reconnect和ServerAliveInterval