我在macOS 10.15.7上运行OpenJDK 14。我正在进行一些概念验证代码,用Apache Mina SSHD建立一个SSH服务器,然后连接到它。以下是我的代码:
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.server.ServerBuilder;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.AsyncAuthException;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.password.PasswordChangeRequiredException;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.shell.InteractiveProcessShellFactory;
import org.apache.sshd.server.shell.ProcessShellFactory;
public class FunctionalTest
{
private static class TestAuthenticator
extends AbstractLoggingBean
implements PasswordAuthenticator
{
@Override
public boolean authenticate(String username, String password, ServerSession session)
throws PasswordChangeRequiredException, AsyncAuthException
{
if ("test".equals(username) && "foobar".equals(password))
{
this.log.info("authenticate({}[{}]: accepted", username, session);
return true;
}
this.log.warn("authenticate({}[{}]: rejected", username, session);
return false;
}
}
public static void main(String... args) throws IOException
{
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setHost("0.0.0.0");
sshd.setPort(1022);
sshd.setShellFactory(InteractiveProcessShellFactory.INSTANCE);
sshd.setPasswordAuthenticator(new TestAuthenticator());
sshd.setCipherFactories(Arrays.asList(BuiltinCiphers.aes256ctr, BuiltinCiphers.aes192ctr));
sshd.setKeyExchangeFactories(ServerBuilder.setUpDefaultKeyExchanges(false));
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Paths.get("key.ser")));
sshd.start();
try
{
Thread.sleep(3_600_000);
}
catch(InterruptedException e)
{
System.out.println("Caught interrupt ... stopping server.");
sshd.stop(true);
}
}
}
当我启动这个程序后,可以使用密码
foobar
通过ssh -p 1022 test@localhost
进行认证,并且可以正常工作。在成功认证后,我首先看到这个:sh: no job control in this shell
那么在提示符处,我输入的字符(包括换行符)会被重复两次回显,导致所有东西都被复制一遍:
williamsn:mina-test williamsn$ llss --aall
total 24
... (list of files)
williamsn:mina-test williamsn$ eecchhoo hheelllloo
hello
williamsn:mina-test williamsn$
此外,如果我运行像
top
这样的交互式命令,它不会识别我的输入,控制字符也无法工作。虽然ttoopp
启动了(但其输出是丑陋的,并且会累加到屏幕上而不是替换之前的内容),但如果我键入q
退出(此时q
不会被回显两次),top
不会响应q
退出。它只会继续运行。ctrl+c
也无法工作——top
只会继续运行。唯一退出top
的方法是杀死我的ssh
进程或关闭MINA服务器。我觉得我在这里一定做错了什么,请问您有何想法?
sh
,结果行为完全相同,只是措辞不同:我使用了sshd.setShellFactory(new ProcessShellFactory("bash", "/usr/local/bin/bash", "-i"));
(请注意,ProcessShellFactory
文档已经过时,现在需要新的第一个参数),输出如下面的评论所示: - Nick Williams