Windows下使用git访问Gitea远程库失败问题

这几天由于个人需要在Windows系统上使用Gitea搭建了一个代码仓库,考虑到Windows没有很方便的SSH服务就直接使用了Gitea的内建SSH。但是在使用Git Bash里的git直接访问代码仓库时会出现以下报错:

Cloning into 'test'...
git@127.0.0.1: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

网上直接搜了下这个报错信息,都是让给Gitea增加SSH Keys,但是我明明已经增加了正确的密钥。更关键的,如果是通过TortoiseGit访问的话就是没有问题的。而Git Bash里的git访问GitHub又是好用的,这就十分尴尬了。于是:

1. 从Gitea日志中找有用信息

Gitea中的日志配置信息加详细:

[log]
MODE      = file
LEVEL     = trace
ROOT_PATH = D:/software/gitea/log

然后可以从日志中找到问题所在:

2021/11/26 15:38:27 modules/ssh/ssh.go:259:sshConnectionFailed() [W] Failed connection from 127.0.0.1:1037 with error: [ssh: no auth passed yet]
2021/11/26 15:38:27 modules/ssh/ssh.go:261:sshConnectionFailed() [W] Failed authentication attempt from 127.0.0.1:1037

2. 撸Gitea源码找问题源头

ssh.go文件涉案源码如下:

// sshConnectionFailed logs a failed connection
// -  this mainly exists to give a nice function name in logging
func sshConnectionFailed(conn net.Conn, err error) {
    // Log the underlying error with a specific message
    log.Warn("Failed connection from %s with error: %v", conn.RemoteAddr(), err)
    // Log with the standard failed authentication from message for simpler fail2ban configuration
    log.Warn("Failed authentication attempt from %s", conn.RemoteAddr())
}

// Listen starts a SSH server listens on given port.
func Listen(host string, port int, ciphers []string, keyExchanges []string, macs []string) {
    srv := ssh.Server{
        Addr:             net.JoinHostPort(host, strconv.Itoa(port)),
        PublicKeyHandler: publicKeyHandler,
        Handler:          sessionHandler,
        ServerConfigCallback: func(ctx ssh.Context) *gossh.ServerConfig {
            config := &gossh.ServerConfig{}
            config.KeyExchanges = keyExchanges
            config.MACs = macs
            config.Ciphers = ciphers
            return config
        },
        ConnectionFailedCallback: sshConnectionFailed,
        // We need to explicitly disable the PtyCallback so text displays
        // properly.
        PtyCallback: func(ctx ssh.Context, pty ssh.Pty) bool {
            return false
        },
    }

    // ...
}

可见错误是从一个回调函数中报出来的,而这个回调则是Go的原生模块ssh里出错后调用的。

3. 再看Go的锅

Go官网被X,Google Code也被X,百度搜索又啥都没有;不要紧,Bing国际版还是给力的,go ssh: no auth passed yet第一条结果就够用了:

Variables

View Source

var ErrNoAuth = errors.New("ssh: no auth passed yet")

ErrNoAuth is the error value returned if no authentication method has been passed yet. This happens as a normal part of the authentication loop, since the client first tries 'none' authentication to discover available methods. It is returned in ServerAuthError.Errors from NewServerConn.

原来GoSSH服务器不响应客户端未定义认证类型的请求。

4. 打完收功

这样就只能从ssh_config下手了,在配置中增加:

Host 127.0.0.1
        HostKeyAlgorithms +ssh-rsa
        PubkeyAcceptedAlgorithms +ssh-rsa

世界瞬间美好了。

添加新评论