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

Issues with RetrieveSupportedCipherSuites #60

Open
lukeyeager opened this issue Aug 29, 2023 · 4 comments
Open

Issues with RetrieveSupportedCipherSuites #60

lukeyeager opened this issue Aug 29, 2023 · 4 comments

Comments

@lukeyeager
Copy link
Contributor

I noticed today that I was failing to scrape a lot of nodes with errors like this:

create session error: none of the provided cipher suite options were supported by the BMC

When I switched from NewSesssion to NewV2Session explicitly setting CipherSuites: []ipmi.CipherSuite{ipmi.CipherSuite17}, things got much better! I can now scrape ~260 nodes intead of ~180 nodes.
image

  1. That shouldn't have helped. The default suite list is [17,3], so RetrieveSupportedCipherSuites should have successfully determined that suite 17 was ok to use.
  2. After using the exporter in the new mode (explicitly setting cipher suite 17) for a few minutes, I reverted the code back to the old code and now those 80 nodes are still working properly. I'm saying that when I skip the RetrieveSupportedCipherSuites once, it puts the BMC into a new state where your library can now run RetrieveSupportedCipherSuites without errors. I don't understand that.
  3. Annoyingly, whenever I use RetrieveSupportedCipherSuites, useful error messages such as RAKP2 HMAC fail (this indicates the BMC is using a different password) are masked, and the library prints an error about unsupported cipher suites intead
@gebn
Copy link
Owner

gebn commented Sep 16, 2023

1 and 2 will need more work. 3 sounds fixable, but can I clarify: RetrieveSupportedCipherSuites() is by definition a sessionless operation; is it that you're getting the RAKP2 HMAC fail after using the result(s) returned by RetrieveSupportedCipherSuites()?

@lukeyeager
Copy link
Contributor Author

Does this example answer your question? I'm noticing today that I sometimes get other errors, too, when I fail to specify the CipherSuite - not only "none of the provided cipher suite options were supported by the BMC".

$ go run ./... "${host}" "${ipmiuser}" "${ipmipw}"
2023/09/18 08:26:22 Connecting with CipherSuites=[]ipmi.CipherSuite{} ...
2023/09/18 08:26:22 new session: none of the provided cipher suite options were supported by the BMC
2023/09/18 08:26:22 Connecting with CipherSuites=[]ipmi.CipherSuite{ipmi.CipherSuite{AuthenticationAlgorithm:0x3, IntegrityAlgorithm:0x4, ConfidentialityAlgorithm:0x1}} ...
2023/09/18 08:26:22 Success.

$ go run ./... "${host}" "${ipmiuser}" "${ipmipw}"
2023/09/18 08:29:09 Connecting with CipherSuites=[]ipmi.CipherSuite{} ...
2023/09/18 08:29:09 new session: expected start of record, got 0x0
2023/09/18 08:29:09 Connecting with CipherSuites=[]ipmi.CipherSuite{ipmi.CipherSuite{AuthenticationAlgorithm:0x3, IntegrityAlgorithm:0x4, ConfidentialityAlgorithm:0x1}} ...
2023/09/18 08:29:09 Success.
package main

import (
        "context"
        "log"
        "os"
        "time"

        "github.com/gebn/bmc"
        "github.com/gebn/bmc/pkg/ipmi"
)

func connect(transport *bmc.V2SessionlessTransport, user, pw string, cipherSuites []ipmi.CipherSuite) {
        log.Printf("Connecting with CipherSuites=%#v ...", cipherSuites)
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()
        session, err := transport.NewV2Session(ctx, &bmc.V2SessionOpts{
                SessionOpts: bmc.SessionOpts{
                        Username:          user,
                        Password:          []byte(pw),
                        MaxPrivilegeLevel: ipmi.PrivilegeLevelUser,
                },
                CipherSuites: cipherSuites,
        })
        if err != nil {
                log.Printf("new session: %v", err)
        } else {
                log.Printf("Success.")
                ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
                defer cancel()
                if err := session.Close(ctx); err != nil {
                        log.Printf("close session: %v", err)
                }
        }
}

func main() {
        host := os.Args[1]
        user := os.Args[2]
        pw := os.Args[3]

        transport, err := bmc.DialV2(host)
        if err != nil {
                log.Fatalf("dial: %v", err)
        }
        defer transport.Close()

        connect(transport, user, pw, []ipmi.CipherSuite{})
        connect(transport, user, pw, []ipmi.CipherSuite{ipmi.CipherSuite17})
}

@lukeyeager
Copy link
Contributor Author

I'm very willing to believe that (1) and (2) are just badly-behaved BMCs. Happy to send a ipmitool -v trace to you if there's anything I can run which would help you verify that this library is working fine (possibly ipmitool channel getciphers ipmi 1?).

@gebn
Copy link
Owner

gebn commented Sep 22, 2023

The ipmitool output for both would be interesting, however I'm not sure 1 is the correct channel value. Does it accept channel 14 (present interface)? The first response breaks the spec in that suite 3 is essential, and the second should never return 0x00 as the first byte of a cipher suite record. I'll try to reproduce this and see what's going on.

If only one suite is passed when creating the session, we bypass Get Channel Cipher Suites entirely, which will be why those are working. If ipmitool is making some assumptions, or being more aggressive with discovery, we should probably emulate that to ensure compatibility - it's more important to be useful than correct. I'll try to reproduce this and see what's going on.

For 3, can you provide a code sample - I'm still confused how RetrieveSupportedCipherSuites() could lead to RAKP2 HMAC fail, unless it's suggesting the BMC supports something it doesn't, which is then causing the HMAC error during session establishment.

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