A self-extracting upgrade tool for Linux that packages a software directory into a single executable shell script (.run). The generated script automatically verifies its signature, decrypts its payload, extracts the archive, and executes install.sh.
Security model:
- Signing: ECDSA P-256 with SHA-256 (sender's private key signs, sender's public key is embedded for verification)
- Encryption: ECIES hybrid encryption using ECDH P-256 to protect a random AES-256 session key (recipient's public key encrypts, recipient's private key decrypts)
Signing and encryption are mandatory for every package.
- Single-file
.runupgrade package - Mandatory ECDSA signature verification before extraction
- Mandatory ECIES encryption of payload using recipient's public key
- Random AES-256 session key per package
- Automatic cleanup of temporary files via
trap - Optional overall signature of the entire
.runfile (outputs.run.sig)
Build from source with Go 1.22 or later:
go build -o seu .The binary is named seu by default. You can rename it as needed.
Generate a new ECDSA P-256 public/private key pair.
seu generateKeys -o <prefix>Flags:
-o, --output string: output path prefix. Generates<prefix>.keyand<prefix>.pub. If omitted, keys are printed to stdout.-h, --help: help for generateKeys.
Example:
seu generateKeys -o sender
seu generateKeys -o recipient
ls sender.* recipient.*
# sender.key sender.pub recipient.key recipient.pubThe .key file is created with permissions 0600.
Create a new self-extracting upgrade package. Encryption and signing are mandatory.
seu make \
-s <source-dir> \
-d <dest-prefix> \
-k <sender-private-key> \
--sender-pub <sender-public-key> \
-r <recipient-public-key> \
[-O]Flags:
-s, --source string: source directory path. Must containinstall.sh.-d, --dest string: destination file prefix. Produces<prefix>and<prefix>.run.-k, --sender-key string: sender's private key file (for ECDSA signing).--sender-pub string: sender's public key file (embedded in.runfor verification).-r, --recipient-pub string: recipient's public key file (for ECIES session-key encryption).-O, --overall-sign: additionally sign the entire.runfile and write<prefix>.run.sig.-h, --help: help for make.
Example:
seu make -s ./myapp -d ./myapp-upgrade \
-k sender.key --sender-pub sender.pub \
-r recipient.pub -OOutput:
myapp-upgrade # encrypted payload (intermediate file)
myapp-upgrade.run # self-extracting script
myapp-upgrade.run.sig # optional overall signature
Display the version of the tool.
seu version./seu generateKeys -o sender
./seu generateKeys -o recipientDistribute sender.pub with the package. Keep recipient.key secret on the target machine.
myapp/
├── install.sh # required, executed after extraction
└── ... # other files and directories
install.sh must exist in the source directory. It will be placed at the root of the extracted archive and executed by bash.
./seu make -s myapp -d myapp-upgrade \
-k sender.key --sender-pub sender.pub \
-r recipient.pub./myapp-upgrade.run recipient.keyThe script will:
- Verify the ECDSA signature using the embedded
sender.pub. - Use
recipient.keyto derive the ECIES shared secret and decrypt the session key. - Decrypt the payload with the session key.
- Extract the archive to a temporary directory.
- Execute
install.sh. - Clean up the temporary directory.
If you built with -O, distribute the .run.sig file alongside the .run file. Verify on the target machine before execution:
openssl dgst -sha256 -verify sender.pub \
-signature myapp-upgrade.run.sig myapp-upgrade.runThe target machine must have:
bashopenssl(1.1.1 or later, withpkeyutl -derivesupport)xxdtarmktempawk
- Sender key pair: signs the package. Protect the private key; distribute only the public key.
- Recipient key pair: decrypts the package. Protect the private key on the target machine; the public key is used during packaging.
- The AES session key is randomly generated per package and never stored in plain text.
- The
.runscript writes PEM keys and temporary files to a directory created bymktempand removes it on exit viatrap. - Do not pass private keys as command-line arguments to the
makecommand; always use file paths (-k).
Feel free to contribute to the project or report issues!