opentofu / get.opentofu.org

The website hosting the OpenTofu Installer script and installation resources
Apache License 2.0
4 stars 8 forks source link

Self-update for shell scripts #6

Open ghost opened 9 months ago

ghost commented 9 months ago

Add a functionality that updates the installer script from the installer script while making sure that the script is correctly signed. This requires the scripts to be signed via GPG / a code signing certificate.

This is currently a low priority issue, please thumbs up this issue if this is important for you.

ksemele commented 5 months ago

Is https://github.com/opentofu/get.opentofu.org/issues/7 a blocker? I have a little experience with bash signing files with OpenSSL (I sign my invoices and allow the people to check them: https://github.com/ksemele/digital-signature/blob/main/check-sign-file.sh#L40)

I can help with this, GPG signing looks similar. If you know of any examples of tools with expected behavior, please provide them to me.

ghost commented 5 months ago

@ksemele I don't think it is, we have GPG keys for signing if we need it. I think it is mostly a question of putting in the hours to do it and test it, plus coming up with the release pipeline.

It would be nice if it worked on Windows (PS) too, but worst case I can just port whatever solution we have for .sh. One thing to note is that we currently support all POSIX shells.

ksemele commented 5 months ago

Yeah, sure. I made some tests with basic GPG signing, so I think if we implement these basic commands, it will be enough.

gpg --output install-opentofu.sh.sig --detach-sig install-opentofu.sh
# I used my own key for tests
gpg --export 427C6873A344E34471FFA017BFF244DED7D0B070 > ./gpgv_keyring.gpg

gpgv --keyring ./gpgv_keyring.gpg install-opentofu.sh.sig install-opentofu.sh
# or this if keys already installed in keychain
gpg --verify install-opentofu.sh.sig install-opentofu.sh

So I suppose implement a new func in .sh like that:

check_gpg_signed() {
  if ! gpgv --keyring ${GPG_FILE} $0.sig $0; then
    log_error "${TOFU_INSTALL_EXIT_CODE_INSTALL_FAILED}"
    exit $?
  fi
}

And refactor main func for adding this check..

download_gpg
check_gpg_signed
# installation
ghost commented 5 months ago

This could be a way to go, but I'm a bit worried about caching since we use Cloudflare. If the script and the signature are cached differently, that can lead to some alarming and unwarranted error messages for users. You can embed data into .sh scripts like this:

#!/bin/sh

...

exit

-----BEGIN PGP SIGNATURE-----
...
-----END GPG SIGNATURE-----

The only thing you need to do in order to verify such a signed script is to add the missing starting line locally. This, of course, will make the script unrunnable, so we can't include it by default. Alternatively, we could transparently version the script in the URL, such as https://get.opentofu.org/install-opentofu.v1.0.0.sh. We could then redirect requests to install-opentofu.sh similar to how we redirect today when someone just opens get.opentofu.org.

One more thing to note: the user should be able to configure where the update server is located, in case someone wants to create a local mirror.