![SFTP 权限被拒绝但 SSH 运行正常](https://linux22.com/image/670769/SFTP%20%E6%9D%83%E9%99%90%E8%A2%AB%E6%8B%92%E7%BB%9D%E4%BD%86%20SSH%20%E8%BF%90%E8%A1%8C%E6%AD%A3%E5%B8%B8.png)
我不断得到没有权限尝试通过 SFTP 上传文件更改时出现错误,但以同一用户身份直接使用 SSH 时运行正常。
我尝试上传的文件是/srv/www/website/current/app/AppKernel.php
(但是该错误当前适用于我的项目中的任何文件,我们将坚持使用一个文件以使事情变得简单)。
我首先要做的就是以同一用户身份通过 SSH 进入服务器,并确认权限正常。
SSH 连接后,我检查我是谁
$ whoami
cp5w
显示ls -l
以下权限(剪切到相关行)
$ ls -l
-rwxrwxr-x 1 deploy nginx 1523 Nov 11 12:51 AppKernel.php
您可以在此处看到文件的所有者是deploy
,组是nginx
。我可以确认用户cp5w
在该组中nginx
:
$ groups
opsworks nginx
那么理论上我应该可以写入AppKernel.php
yes 吗?让我们尝试一下:
$ tail -n 3 AppKernel.php
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml');
}
}
$ echo "# add line to end of file" >> AppKernel.php
$ tail -n 3 AppKernel.php
}
}
# add line to end of file
是的,一切正常。没有错误。我没有发疯。
一些可能的解决方案建议检查父目录上是否有组可执行文件我已仔细检查如下(再次剪辑到相关行):
$ ls -l ..
drwxrwxr-x 6 deploy nginx 4096 Nov 11 15:31 app
我还检查了系统拥有的目录的问题 但是,我已经在处理一个子目录,website
该目录也与项目其余部分共享相同的权限模式:
- 拥有
deploy
- 组是
nginx
- 组可以读取、写入和遍历目录
现在我将尝试使用 SFTP 从我的工作站上传(即修改)文件。相同的用户。相同的 SSH 密钥。相同的工作站。相同的服务器。针对相同的文件。现在只需 SFTP,而不是 SSH。
psftp> open myserver
login as: cp5w
psftp> cd /srv/www/website/current/app
Remote directory is now /srv/www/website/releases/20151111145342/app
psftp> lcd C:\Users\chris\Source\website\app
New local directory is C:\Users\chris\Source\website\app
psftp> put AppKernel.php
/srv/www/website/releases/20151111145342/app/AppKernel.php: open for write: permission denied
是什么赋予了?!!
更多值得思考的内容:
- 这曾经有效几天前通过 SFTP 进行了备份,并且我最近没有对服务器配置进行任何更改
- 这个问题是不是因为我试图通过符号链接进行写入?
- 我最近唯一改变的是我的工作站,现在使用的是 Windows 而不是 Linux。这是对我的惩罚吗?低俗的笑话。说真的,工作站操作系统会影响这一点吗?
去做:
- 从不同的工作站操作系统进行测试
编辑
我检查了 SSH 日志以查看是否可以添加任何有意义的内容,这是尝试上传导致的输出(用 % 占位符隐藏了一些数据):
$ tail -f /var/log/secure
Nov 11 17:46:58 %server% sshd[22455]: Accepted publickey for cp5w from %ip% port %port% ssh2: RSA %fingerprint%
Nov 11 17:46:58 %server% sshd[22455]: pam_unix(sshd:session): session opened for user cp5w by (uid=0)
Nov 11 17:46:58 %server% sshd[22455]: pam_unix(sshd:session): session closed for user cp5w
我还通过修改 sshd_config 并添加-l INFO
以下内容启用了 SFTP 日志:
Subsystem sftp internal-sftp -l INFO
接下来/var/log/messages
是以下内容:
$ tail -f /var/log/messages
Nov 11 18:06:57 %server% internal-sftp[23002]: session opened for local user cp5w from [%ip%]
Nov 11 18:06:57 %server% internal-sftp[23002]: opendir "/srv/www/."
Nov 11 18:06:57 %server% internal-sftp[23002]: closedir "/srv/www/."
Nov 11 18:06:57 %server% internal-sftp[23002]: open "/srv/www/website/current/app/AppKernel.php" flags WRITE,CREATE,TRUNCATE mode 0666
Nov 11 18:06:57 %server% internal-sftp[23002]: sent status Permission denied
Nov 11 18:06:57 %server% internal-sftp[23002]: session closed for local user cp5w from [%ip%]
答案1
我想知道您是否正在运行 selinux,这可能与您的问题有关。getenforce 或 sestatus 会显示什么?如果您正在运行强制执行,那么切换到宽容会发生什么?
如果没有,您能测试并证明 sftp 使用哪个用户帐户代表您写入文件吗?原则上应该是 cp5w,但实际上情况确实如此吗?
最后你可能会发现 chroot 不起作用。没有 chroot 还能工作吗?
祝威尔莫特先生好运。
答案2
核心问题是您的 SFTP 服务器需要 SSH 密钥身份验证才能正确允许连接。您提到了 FileZilla,所以我这样写了这个答案。
在这种情况下,您可以将其用于不受密码保护的 SSH 密钥:
- 打开 FileZilla 客户端。
- 在主屏幕顶部,单击“编辑”并选择“设置”。
- 在菜单左侧,展开“连接”部分并突出显示“SFTP”。
- 点击[添加密钥文件...]按钮,浏览本地机器的目录并选择您的私钥文件。
- 然后,再次从 FileZilla 主屏幕顶部单击“文件”并选择“站点管理器”。
- 最后,在站点管理器的左侧,单击“新建站点”按钮,并在“我的站点”下输入一个唯一的名称,以便您将来可以轻松识别这个特定的远程服务器。
- 现在,在“常规”选项卡下,填写主机(使用 IP 地址或 FQDN)和端口字段(默认为 22)。
- 在协议下拉菜单中,选择 SFTP - SSH 文件传输协议。