gregtwallace / apc-p15-tool

APC P15 Tool is an open source replacement for APC's NMC Security Wizard. It also adds additional functionality for installing certificates on APC NMC2 & NMC3.
GNU General Public License v3.0
21 stars 5 forks source link

Unable to connect to NMC to install cert #1

Closed danb35 closed 9 months ago

danb35 commented 9 months ago

tl;dr: the SSH/SCP connection to my NMC2 fails:

➜  ~ ./apc-p15-tool install --debug --keyfile /home/dan/.acme.sh/ups1.familybrown.org/ups1.familybrown.org.key --certfile /home/dan/.acme.sh/ups1.familybrown.org/ups1.familybrown.org.cer --apchost ups1:22 --username apc --password (redacted) --fingerprint (redacted)
apc-p15-tool v0.3.1
install: making apc p15 file from pem
install: successfully loaded pem files
install: apc p15 file data succesfully generated
install: failed to connect to host (ssh: handshake failed: ssh: no common algorithm for key exchange; client offered: [curve25519-sha256 curve25519-sha256@libssh.org ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 diffie-hellman-group14-sha256 diffie-hellman-group14-sha1 ext-info-c kex-strict-c-v00@openssh.com], server offered: [diffie-hellman-group-exchange-sha256 diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1])
apc-p15-tool done

I've encountered similar problems with my old Ruckus switches, and solved them by creating a per-host SSH config. For the UPS, I've added this to ~/.ssh/config without success:

Host ups1 192.168.1.46
    KexAlgorithms +diffie-hellman-group1-sha1
    Ciphers +aes256-cbc

These changes let me SSH to the UPS, but don't let your tool connect; it still gives the error above.

I'm using a NMC2 in a SmartUPS 3000XLM. The boot monitor version is 1.0.8, APC OS version 6.4.6, and application module version 6.4.6. I've found the boot monitor version 1.0.9 and APC OS version 7.1.2 on APC's website, but haven't yet found the application module for my UPS so I'm hesitant to upgrade--their docs suggest you need to upgrade everything at once.

Edit: of course this happens after I open the ticket--I've found updated firmware that would cover my UPS. Giving that a try.

gregtwallace commented 9 months ago

I'm not sure what OS you're running but attached is a test build that adds the kex "diffie-hellman-group-exchange-sha256". If you get another handshake error with this one, please provide the new error. I didn't modify Go's default included Ciphers, so your error might change to that one depending on what Cipher's your device supports.

If you have ssh on a linux box, you can run ssh -vv myups.example.com and server KEXINIT will tell you exactly what is supported.

debug2: peer server KEXINIT proposal
debug2: KEX algorithms: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,ecdh-sha2-nistp256
debug2: host key algorithms: ssh-rsa
debug2: ciphers ctos: aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbc
debug2: ciphers stoc: aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbc
debug2: MACs ctos: hmac-sha2-256,hmac-sha1
debug2: MACs stoc: hmac-sha2-256,hmac-sha1
debug2: compression ctos: none
debug2: compression stoc: none
debug2: languages ctos:
debug2: languages stoc:

edit: try v0.3.2 - I added the algorithm.

danb35 commented 9 months ago

I'm not sure what OS you're running

Yeah, I guess that would have been relevant--it's Debian 12. Here's the output of ssh -vv:

➜  ~ ssh -vv apc@ups1
OpenSSH_8.4p1 Debian-5+deb11u3, OpenSSL 1.1.1w  11 Sep 2023
debug1: Reading configuration data /home/dan/.ssh/config
debug1: /home/dan/.ssh/config line 1: Applying options for ups1
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug2: resolving "ups1" port 22
debug2: ssh_connect_direct
debug1: Connecting to ups1 [192.168.1.46] port 22.
debug1: Connection established.
debug1: identity file /home/dan/.ssh/id_rsa type -1
debug1: identity file /home/dan/.ssh/id_rsa-cert type -1
debug1: identity file /home/dan/.ssh/id_dsa type -1
debug1: identity file /home/dan/.ssh/id_dsa-cert type -1
debug1: identity file /home/dan/.ssh/id_ecdsa type -1
debug1: identity file /home/dan/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/dan/.ssh/id_ecdsa_sk type -1
debug1: identity file /home/dan/.ssh/id_ecdsa_sk-cert type -1
debug1: identity file /home/dan/.ssh/id_ed25519 type -1
debug1: identity file /home/dan/.ssh/id_ed25519-cert type -1
debug1: identity file /home/dan/.ssh/id_ed25519_sk type -1
debug1: identity file /home/dan/.ssh/id_ed25519_sk-cert type -1
debug1: identity file /home/dan/.ssh/id_xmss type -1
debug1: identity file /home/dan/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u3
debug1: Remote protocol version 2.0, remote software version cryptlib
debug1: no match: cryptlib
debug2: fd 3 setting O_NONBLOCK
debug1: Authenticating to ups1:22 as 'apc'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group1-sha1,ext-info-c,kex-strict-c-v00@openssh.com
debug2: host key algorithms: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ecdsa-sha2-nistp256@openssh.com,ssh-ed25519,sk-ssh-ed25519@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa
debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes256-cbc
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes256-cbc
debug2: MACs ctos: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
debug2: MACs stoc: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
debug2: compression ctos: none,zlib@openssh.com,zlib
debug2: compression stoc: none,zlib@openssh.com,zlib
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
debug2: host key algorithms: ssh-rsa
debug2: ciphers ctos: aes256-cbc,3des-cbc
debug2: ciphers stoc: aes256-cbc,3des-cbc
debug2: MACs ctos: hmac-sha2-256,hmac-sha1,hmac-md5
debug2: MACs stoc: hmac-sha2-256,hmac-sha1,hmac-md5
debug2: compression ctos: none
debug2: compression stoc: none
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
debug1: kex: algorithm: diffie-hellman-group-exchange-sha256
debug1: kex: host key algorithm: ssh-rsa
debug1: kex: server->client cipher: aes256-cbc MAC: hmac-sha2-256 compression: none
debug1: kex: client->server cipher: aes256-cbc MAC: hmac-sha2-256 compression: none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(2048<8192<8192) sent
debug1: got SSH2_MSG_KEX_DH_GEX_GROUP
debug2: bits set: 982/2048
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: got SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: ssh-rsa SHA256:ym48dMebiTxs0NFWth7Pg8Sx2R1slIknL2L1O6LuiME
The authenticity of host 'ups1 (192.168.1.46)' can't be established.
RSA key fingerprint is SHA256:(redacted).

I'll try 0.3.2. Edit: I thought the cipher would still be a problem. Here's what happens with 0.3.2:

apc-p15-tool v0.3.2
install: making apc p15 file from pem
install: successfully loaded pem files
install: apc p15 file data succesfully generated
install: failed to connect to host (ssh: handshake failed: ssh: no common algorithm for client to server cipher; client offered: [aes128-gcm@openssh.com aes256-gcm@openssh.com chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr], server offered: [aes256-cbc 3des-cbc])
apc-p15-tool done
gregtwallace commented 9 months ago

Ah. Anything CBC is considered insecure for SSH. It doesn't even look like golang supports aes256-cbc.

I can add the 3des option but I'll probably also add another flag to require explicit acknowledgement of the inherent insecurity.

gregtwallace commented 9 months ago

Try this. You'll need to add the --insecurecipher flag.

apc-p15-tool-amd64.zip

danb35 commented 9 months ago

That seems to have done the job:

apc-p15-tool v0.3.2
install: making apc p15 file from pem
install: successfully loaded pem files
install: apc p15 file data succesfully generated
2024/02/04 16:29:44 [aes128-gcm@openssh.com aes256-gcm@openssh.com chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc 3des-cbc]
debug: ssh: remote server key fingerprint (b64): ym48dMebiTxs0NFWth7Pg8Sx2R1slIknL2L1O6LuiME
debug: ssh: remote server key fingerprint (hex): ca6e3c74c79b893c6cd0d156b61ecf83c4b1d91d6c9489272f62f53ba2ee88c1
install: apc p15 file installed on ups1:22
apc-p15-tool done

If I can get the firmware updates to install, the --insecurecipher probably won't be necessary, but the card isn't letting me send them via either FTP or SCP--but that's a separate issue.

What environment variable would I use to pass the --insecurecipher using LeGo CertHub?

gregtwallace commented 9 months ago

All of the environment variables are the same as the args but with the prefix APC_P15_TOOL_. So, this one would be APC_P15_TOOL_INSECURECIPHER. I think you can set it to any value but true is probably a good, sane practice.

I'll pust the official new version shortly which includes a log message when using the bad ciphers.

danb35 commented 9 months ago

Just for the record, I've now managed to get the NMC2 firmware updated to 7.1.2 (apparently rebooting the NMC--which I had to do to enable HTTPS--also reset whatever wasn't allowing firmware uploads), and I no longer need the --insecurecipher flag. Version 6.4.6 does need it.

gregtwallace commented 9 months ago

Good to know. Still a good addition I think.