如何调试 org.apache.sshd.common.scp.ScpException: Received nack: Can not write to error?
How to debug org.apache.sshd.common.scp.ScpException: Received nack: Can not write to error?
我正在编写一个用于测试 SSH 连接的工具,具有基本功能:连接、上传文件、下载文件。
我的 SftpTestServer 实现:
import org.apache.sshd.client.SshClient
import org.apache.sshd.client.scp.ScpClientCreator
import org.apache.sshd.client.session.ClientSession
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory
import org.apache.sshd.server.SshServer
import org.apache.sshd.server.auth.password.PasswordAuthenticator
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
import org.apache.sshd.server.scp.ScpCommandFactory
import org.apache.sshd.server.session.ServerSession
import org.apache.sshd.server.subsystem.SubsystemFactory
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory
import java.io.File
import java.nio.file.Paths
import java.util.*
class SftpTestServer(
private val host: String,
private val port: Int,
private val rootDir: File,
private val userName: String,
private val password: String
) : TestServer {
private val server: SshServer
private val client: SshClient
private fun session(): ClientSession {
val session = client.connect(userName, server.host, server.port).verify().session
session.addPasswordIdentity(password)
session.auth().verify().isSuccess
return session
}
override fun start() {
server.start()
client.start()
}
override fun stop() {
client.stop()
server.stop()
}
private fun setupServer(host: String, port: Int, rootDir: File, userName: String, pwd: String): SshServer {
val sshd = SshServer.setUpDefaultServer()
sshd.keyPairProvider = SimpleGeneratorHostKeyProvider(File(rootDir, "sshd_key.ser").toPath())
sshd.fileSystemFactory = VirtualFileSystemFactory(Paths.get(rootDir.absolutePath))
sshd.port = port
sshd.host = host
sshd.passwordAuthenticator = PasswordAuthenticator { username: String, password: String, _: ServerSession? -> username == userName && password == pwd }
sshd.commandFactory = ScpCommandFactory()
val factoryList: MutableList<SubsystemFactory> = ArrayList()
factoryList.add(SftpSubsystemFactory())
sshd.subsystemFactories = factoryList
return sshd
}
fun upload(file: File) {
val creator = ScpClientCreator.instance()
val scpClient = creator.createScpClient(session())
scpClient.upload(Paths.get(file.absolutePath), rootDir.absolutePath)
}
fun listFiles(): List<String> {
return listOf()
}
init {
server = setupServer(host, port, rootDir, userName, password)
client = setupClient()
}
private fun setupClient(): SshClient {
return SshClient.setUpDefaultClient()
}
}
我的 SftpTestServerTest 实现:
import org.apache.commons.io.FileUtils
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.*
import java.io.File
@Tag("servers")
class SftpTestServerTest {
companion object {
private const val HOST: String = "localhost"
private const val PORT: Int = 23456
private val TEST_FILE_RESOURCE: File = File("target/test-folder")
private const val USERNAME: String = "username"
private const val PASSWORD: String = "password"
}
private val server = SftpTestServer(HOST, PORT, TEST_FILE_RESOURCE, USERNAME, PASSWORD)
@BeforeEach
fun setUp() {
server.start()
FileUtils.deleteDirectory(TEST_FILE_RESOURCE)
FileUtils.forceMkdir(TEST_FILE_RESOURCE)
}
@AfterEach
fun tearDown() {
server.stop()
}
@Test
fun `should upload file from file path`() {
val fileName = "src/test/resources/ssh_test_file.xml"
val file = File(fileName)
server.upload(file)
assertThat(server.listFiles()).contains(fileName)
}
}
令人惊讶的是,关于我从 org.apache.sshd
.
得到的错误,我在网上找不到太多信息
org.apache.sshd.common.scp.ScpException: Received nack: Can not write to
如何调试这个错误?
注意:我正在使用 Mac。不过,这个问题不应该是 OS 特有的。
问题是我使用 SSH 客户端连接到 SSH 服务器内部的错误路径。
因此,我对调试此问题的建议:
- 检查您对文件系统reading/writing的权限
- 连接到 SSH 服务器,检查文件夹结构
- 在前面步骤的基础上,修复 SSH Client 连接中的问题
我正在编写一个用于测试 SSH 连接的工具,具有基本功能:连接、上传文件、下载文件。
我的 SftpTestServer 实现:
import org.apache.sshd.client.SshClient
import org.apache.sshd.client.scp.ScpClientCreator
import org.apache.sshd.client.session.ClientSession
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory
import org.apache.sshd.server.SshServer
import org.apache.sshd.server.auth.password.PasswordAuthenticator
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
import org.apache.sshd.server.scp.ScpCommandFactory
import org.apache.sshd.server.session.ServerSession
import org.apache.sshd.server.subsystem.SubsystemFactory
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory
import java.io.File
import java.nio.file.Paths
import java.util.*
class SftpTestServer(
private val host: String,
private val port: Int,
private val rootDir: File,
private val userName: String,
private val password: String
) : TestServer {
private val server: SshServer
private val client: SshClient
private fun session(): ClientSession {
val session = client.connect(userName, server.host, server.port).verify().session
session.addPasswordIdentity(password)
session.auth().verify().isSuccess
return session
}
override fun start() {
server.start()
client.start()
}
override fun stop() {
client.stop()
server.stop()
}
private fun setupServer(host: String, port: Int, rootDir: File, userName: String, pwd: String): SshServer {
val sshd = SshServer.setUpDefaultServer()
sshd.keyPairProvider = SimpleGeneratorHostKeyProvider(File(rootDir, "sshd_key.ser").toPath())
sshd.fileSystemFactory = VirtualFileSystemFactory(Paths.get(rootDir.absolutePath))
sshd.port = port
sshd.host = host
sshd.passwordAuthenticator = PasswordAuthenticator { username: String, password: String, _: ServerSession? -> username == userName && password == pwd }
sshd.commandFactory = ScpCommandFactory()
val factoryList: MutableList<SubsystemFactory> = ArrayList()
factoryList.add(SftpSubsystemFactory())
sshd.subsystemFactories = factoryList
return sshd
}
fun upload(file: File) {
val creator = ScpClientCreator.instance()
val scpClient = creator.createScpClient(session())
scpClient.upload(Paths.get(file.absolutePath), rootDir.absolutePath)
}
fun listFiles(): List<String> {
return listOf()
}
init {
server = setupServer(host, port, rootDir, userName, password)
client = setupClient()
}
private fun setupClient(): SshClient {
return SshClient.setUpDefaultClient()
}
}
我的 SftpTestServerTest 实现:
import org.apache.commons.io.FileUtils
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.*
import java.io.File
@Tag("servers")
class SftpTestServerTest {
companion object {
private const val HOST: String = "localhost"
private const val PORT: Int = 23456
private val TEST_FILE_RESOURCE: File = File("target/test-folder")
private const val USERNAME: String = "username"
private const val PASSWORD: String = "password"
}
private val server = SftpTestServer(HOST, PORT, TEST_FILE_RESOURCE, USERNAME, PASSWORD)
@BeforeEach
fun setUp() {
server.start()
FileUtils.deleteDirectory(TEST_FILE_RESOURCE)
FileUtils.forceMkdir(TEST_FILE_RESOURCE)
}
@AfterEach
fun tearDown() {
server.stop()
}
@Test
fun `should upload file from file path`() {
val fileName = "src/test/resources/ssh_test_file.xml"
val file = File(fileName)
server.upload(file)
assertThat(server.listFiles()).contains(fileName)
}
}
令人惊讶的是,关于我从 org.apache.sshd
.
org.apache.sshd.common.scp.ScpException: Received nack: Can not write to
如何调试这个错误?
注意:我正在使用 Mac。不过,这个问题不应该是 OS 特有的。
问题是我使用 SSH 客户端连接到 SSH 服务器内部的错误路径。
因此,我对调试此问题的建议:
- 检查您对文件系统reading/writing的权限
- 连接到 SSH 服务器,检查文件夹结构
- 在前面步骤的基础上,修复 SSH Client 连接中的问题