是否可以配置 OpenSSH(或任何其他标准 sshd)来接受连接客户端提供的任何密钥?
EGssh -i ~/arbitraryKey hostname
授予登录 shell,但ssh hostanme
不授予。
我问这个问题是因为有一个关于配置错误的服务器的轶事,但我已经看过了,但我找不到任何可以真正让这种情况发生的东西,而不需要某种形式的故意黑客攻击守护进程。 (重新编译等)
答案1
使用 PAM 将 SSH 服务器配置为接受任何密码会很容易 — 将其放在堆栈pam_permit
上auth
,然后瞧。错误配置这样一个开放系统的可能性是 PAM 灵活性所固有的——因为它允许您根据需要链接尽可能多的测试,所以进行 0 次测试的可能性是不可避免的(至少不会引入无法涵盖所有情况的奇怪异常) )。
密钥身份验证不通过 PAM,并且没有“接受任何密钥”的配置设置。这仅在极少数情况下有用(用于测试或蜜罐),因此不值得将其作为选项提供(具有配置错误的固有风险)。
答案2
Gilles 建议匿名 ssh 配置“仅在极其罕见的情况下有用”,但其中一种罕见的情况是特马特服务,世界各地的开发人员都使用该服务进行结对编程和其他类型的共享终端会话。
您可以使用帕拉米科Python 库用于创建一个ssh
服务器,该服务器将接受使用任何公钥的连接,但这将拒绝不提供任何密钥的连接。
例如:
#!/usr/bin/python
import paramiko
import socket
import threading
host_key = paramiko.RSAKey(filename='hostkey')
class Server(paramiko.ServerInterface):
def __init__(self):
self.event = threading.Event()
def check_channel_request(self, kind, chanid):
if kind == 'session':
return paramiko.OPEN_SUCCEEDED
def check_auth_publickey(self, username, key):
return paramiko.AUTH_SUCCESSFUL
def get_allowed_auths(self, username):
return 'publickey'
def check_channel_exec_request(self, channel, command):
# This is the command we need to parse
print('client sent command: {}'.format(command))
self.event.set()
return True
def listener():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 2222))
sock.listen(100)
client, addr = sock.accept()
t = paramiko.Transport(client)
t.set_gss_host(socket.getfqdn(""))
t.load_server_moduli()
t.add_server_key(host_key)
server = Server()
t.start_server(server=server)
# Wait 30 seconds for a command
server.event.wait(30)
t.close()
while True:
try:
listener()
except KeyboardInterrupt:
pass
这将允许私钥可用的 ssh 连接。没关系哪个密钥正在被使用。它将拒绝任何无法进行公钥身份验证的连接。