Issues with RetrieveSupportedCipherSuites
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.
- That shouldn't have helped. The default suite list is
[17,3], soRetrieveSupportedCipherSuitesshould have successfully determined that suite 17 was ok to use. - 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
RetrieveSupportedCipherSuitesonce, it puts the BMC into a new state where your library can now runRetrieveSupportedCipherSuiteswithout errors. I don't understand that. - Annoyingly, whenever I use
RetrieveSupportedCipherSuites, useful error messages such asRAKP2 HMAC fail (this indicates the BMC is using a different password)are masked, and the library prints an error about unsupported cipher suites intead
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()?
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})
}
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?).
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.