Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请问支持这个参数吗PubkeyAcceptedKeyTypes=+ssh-dss #22

Closed
qinkangdeid opened this issue Nov 28, 2019 · 11 comments
Closed

请问支持这个参数吗PubkeyAcceptedKeyTypes=+ssh-dss #22

qinkangdeid opened this issue Nov 28, 2019 · 11 comments

Comments

@qinkangdeid
Copy link

目前运维要求在~/.ssh/config
这样的才能连接上跳板机器

Host xxx
HostName xxx
User username
Port 3223
IdentityFile  ~/.ssh/id_dsa
PubkeyAcceptedKeyTypes=+ssh-dss

我看了一下 只有一行 PubkeyAcceptedKeyTypes=+ssh-dss 不太一样

@mritd
Copy link
Owner

mritd commented Nov 28, 2019

PubkeyAcceptedKeyTypes 参数的作用是开启 ssh dsa 支持;而 dsa 是已经被淘汰的加密方式,现在已经不推荐使用;不过 ssh 公钥解析部份由 golang 标准库提供,从标准库源码中看到应该是支持的

// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
// supports RSA (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys.
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
	block, _ := pem.Decode(pemBytes)
	if block == nil {
		return nil, errors.New("ssh: no key found")
	}

	if encryptedBlock(block) {
		return nil, errors.New("ssh: cannot decode encrypted private keys")
	}

	switch block.Type {
	case "RSA PRIVATE KEY":
		return x509.ParsePKCS1PrivateKey(block.Bytes)
	// RFC5208 - https://tools.ietf.org/html/rfc5208
	case "PRIVATE KEY":
		return x509.ParsePKCS8PrivateKey(block.Bytes)
	case "EC PRIVATE KEY":
		return x509.ParseECPrivateKey(block.Bytes)
	case "DSA PRIVATE KEY":
		return ParseDSAPrivateKey(block.Bytes)
	case "OPENSSH PRIVATE KEY":
		return parseOpenSSHPrivateKey(block.Bytes)
	default:
		return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
	}
}

@qinkangdeid
Copy link
Author

目前按照往常设置会报无法解密私钥

~ mmh
» jumphost: username@host
ssh: cannot decode encrypted private keys
😱 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none], no supported methods remain

@mritd
Copy link
Owner

mritd commented Nov 29, 2019

刚刚测试通过 ssh-keygen -t dsa 生成的 dsa 私钥是无法使用的,通过源码发现 golang 并不支持已经被废弃的 openssl dsa 私钥加密(详见 issue #23751),具体源码如下

// Implemented based on the documentation at
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
func parseOpenSSHPrivateKey(key []byte) (crypto.PrivateKey, error) {
	const magic = "openssh-key-v1\x00"
	if len(key) < len(magic) || string(key[:len(magic)]) != magic {
		return nil, errors.New("ssh: invalid openssh private key format")
	}
	remaining := key[len(magic):]

	var w struct {
		CipherName   string
		KdfName      string
		KdfOpts      string
		NumKeys      uint32
		PubKey       []byte
		PrivKeyBlock []byte
	}

	if err := Unmarshal(remaining, &w); err != nil {
		return nil, err
	}

	if w.KdfName != "none" || w.CipherName != "none" {
		return nil, errors.New("ssh: cannot decode encrypted private keys")
	}

	pk1 := struct {
		Check1  uint32
		Check2  uint32
		Keytype string
		Rest    []byte `ssh:"rest"`
	}{}

	if err := Unmarshal(w.PrivKeyBlock, &pk1); err != nil {
		return nil, err
	}

	if pk1.Check1 != pk1.Check2 {
		return nil, errors.New("ssh: checkint mismatch")
	}

	// we only handle ed25519 and rsa keys currently
	switch pk1.Keytype {
	case KeyAlgoRSA:
		// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
		key := struct {
			N       *big.Int
			E       *big.Int
			D       *big.Int
			Iqmp    *big.Int
			P       *big.Int
			Q       *big.Int
			Comment string
			Pad     []byte `ssh:"rest"`
		}{}

		if err := Unmarshal(pk1.Rest, &key); err != nil {
			return nil, err
		}

		for i, b := range key.Pad {
			if int(b) != i+1 {
				return nil, errors.New("ssh: padding not as expected")
			}
		}

		pk := &rsa.PrivateKey{
			PublicKey: rsa.PublicKey{
				N: key.N,
				E: int(key.E.Int64()),
			},
			D:      key.D,
			Primes: []*big.Int{key.P, key.Q},
		}

		if err := pk.Validate(); err != nil {
			return nil, err
		}

		pk.Precompute()

		return pk, nil
	case KeyAlgoED25519:
		key := struct {
			Pub     []byte
			Priv    []byte
			Comment string
			Pad     []byte `ssh:"rest"`
		}{}

		if err := Unmarshal(pk1.Rest, &key); err != nil {
			return nil, err
		}

		if len(key.Priv) != ed25519.PrivateKeySize {
			return nil, errors.New("ssh: private key unexpected length")
		}

		for i, b := range key.Pad {
			if int(b) != i+1 {
				return nil, errors.New("ssh: padding not as expected")
			}
		}

		pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
		copy(pk, key.Priv)
		return &pk, nil
	default:
		return nil, errors.New("ssh: unhandled key type")
	}
}

@mritd
Copy link
Owner

mritd commented Nov 29, 2019

@qinkangdeid 或者你提供一下你的私钥头部前缀,我看看源码;目前从源码上看 前缀是 DSA PRIVATE KEY 可以,如果前缀是 OPENSSH PRIVATE KEY 则不行

@mritd
Copy link
Owner

mritd commented Nov 29, 2019

还有确认以下你的 私钥是否需要密码

@qinkangdeid
Copy link
Author

@qinkangdeid 或者你提供一下你的私钥头部前缀,我看看源码;目前从源码上看 前缀是 DSA PRIVATE KEY 可以,如果前缀是 OPENSSH PRIVATE KEY 则不行

真的是OPENSSH PRIVATE KEY GG了 😫

-----BEGIN OPENSSH PRIVATE KEY-----
adjasidkoasds

-----END OPENSSH PRIVATE KEY-----

@qinkangdeid
Copy link
Author

还有确认以下你的 私钥是否需要密码

我的私钥是有密码的 密码我配在yaml里了

@mritd
Copy link
Owner

mritd commented Nov 29, 2019

你得 dsa 头是什么?

@qinkangdeid
Copy link
Author

你得 dsa 头是什么?

怎么看 😔 下面是我的部分私钥

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH
NzAAAAgQDuCPREk0wBAi8TXW6scXN64EVC9meCK/hjr6fVVKUlN+chAWdqhknjAgx2bf1T
7ByU5vT1t4lVkwMgqHpHkB0GmOwqposfiTsU5F876RiLvnE61GaNdS55CYwAltvLH1KemP

GTm+8psHgU/YmxQy0vQxSNPEZAcZktw4/vU0FQw5yfuLtglP7/1N99KNHcaqr2yhRcZ+PO
K2TThv+PPKdBJXeMfaE1ekWhexu258xwiA9pEBYAAACBAJIYhv8P0b3WnOjNwqCd5RkI8j
FMXemsjbocXho3b21plVG5xcB7ryCw8d75V3ojmVJrsB1fi4tsRUtNq0uhdkpaRwuKbwH/
bcOkI0MmwE0IB2f70Qui9ZcDtX2ZjS2pNqH8kTUzoN34JNLi9n4DAR77cRlJF0aDqILqvV

MCYAAAAjcWlua2FuZ2RlaWRAcWlua2FuZ2RlaWRzLWlNYWMubG9jYWwBAgMEBQYH
-----END OPENSSH PRIVATE KEY-----

@mritd
Copy link
Owner

mritd commented Nov 29, 2019

你可以试试将 OPENSSH PRIVATE KEY 换成 DSA PRIVATE KEY 😂

@qinkangdeid
Copy link
Author

你可以试试将 OPENSSH PRIVATE KEY 换成 DSA PRIVATE KEY 😂

好的 我重新生成一个试试

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants