Is there a shell that checks to make sure the code is signed?
Solution 1
If you're locking users' ability to run scripts via sudo
then you could use the digest
functionality.
You can specify the hash of a script/executable in sudoers
which will be verified by sudo
before being executed. So although not the same as signing, it gives you a basic guarantee that the script has at least not been modified without sudoers also being modified.
If a command name is prefixed with a Digest_Spec, the command will only match successfully if it can be verified using the specified SHA-2 digest. This may be useful in situations where the user invoking sudo has write access to the command or its parent directory. The following digest formats are supported: sha224, sha256, sha384 and sha512. The string may be specified in either hex or base64 format (base64 is more compact). There are several utilities capable of generating SHA-2 digests in hex format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.
http://www.sudo.ws/man/1.8.13/sudoers.man.html
Solution 2
Yes and no.
Linux software distribution works somewhat differently from Windows software distribution. In the (non-embedded) Linux world, the primary method to distribute software is via a distribution (Ubuntu, Debian, RHEL, Fedora, Arch, etc.). All major distributions have been signing their packages systematically for about a decade.
When software is distributed independently, it's up to the vendor to decide how they'll ship their software. Good vendors provide package sources that's compatible with the major distributions (there's no unified distribution mechanism for all of Linux: software distribution is one of the main points of differentiation between distributions) and that are signed with the vendor's key. Linux distributions rarely act as a signing authority for third-party vendors (Canonical does this with Ubuntu partners, but that covers very few vendors), and I think all major distributions use the PGP web of trust rather than the TLS public key infrastructure, so it's up to the user to figure out whether they want to trust a key.
There's no special mechanism that singles out software packages that consist of a single script from software packages that consist of a native executable, a data file, or multiple files. Nor is any signature verification built into any common script interpreter, because verifying a software package is a completely orthogonal concern from running a script.
I think Windows annotates files with their origin, and requires user confirmation to run a file whose origin is “downloaded” rather than “local”. Linux doesn't really have a similar mechanism. The closest thing is execution permission: a downloaded file does not have execution permission, the user needs to explicitly enable it (chmod +x
on the command line, or the equivalent action in a file manager).
Solution 3
Linux does not provide the capability to limit the execution of bash scripts based on digital signatures.
There is some work on authenticating binary executables. See https://lwn.net/Articles/488906/ for info.
Solution 4
In a word, "no".
Linux doesn't really differentiate between executables and scripts; the #!
at the beginning is a way to tell the kernel what program to run to evaluate the input but it's not the only way a script can be executed.
So, for example, if I have a script
$ cat x
#!/bin/sh
echo hello
Then I can run this with the command
$ ./x
That will cause the kernel to try and execute it, spot the #!
and then effectively run /bin/sh x
instead.
However I could also run any of these variants as well:
$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x
or even
. ./x
So even if the kernel tried to enforce signing at the exec
layer we can bypass this by only running the interpreter with the script as a parameter.
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?
The standard solution to this isn't to use signing, but to use Mandatory Access Controls (MAC), such as SELinux
. With MAC systems you can specify exactly what each user is allowed to run and transition layers. So, for example, you can say "normal users can run anything but the web server and CGI processes can only access stuff from the /var/httpd
directory; everything else is rejected".
Solution 5
Linux distros usually have gnupg. It sounds to me like all you want is a simple bash wrapper that checks a detached gpg signature against the argument script and only proceeds to run the script if the check succeeds:
#!/bin/sh
gpgv2 $1.asc && bash "$@"
Related videos on Youtube
leeand00
Projects jobdb - Creator of Open Source Job Search Document Creator/Tracker http://i9.photobucket.com/albums/a58/Maskkkk/c64nMe.jpg Received my first computer (see above) at the age of 3, wrote my first program at the age of 7. Been hooked on programming ever since.
Updated on September 18, 2022Comments
-
leeand00 over 1 year
I was messing around with PowerShell this week and discovered that you are required to Sign your scripts so that they can be run. Is there any similar secure functionality in Linux that relates to preventing bash scripts from being run?
The only functionality similar to this, that I'm aware of is that of SSH requiring a certain key.
-
Admin almost 8 yearsSounds a bit like an ad-hoc solution to package signing to me. I don't know if Windows has cryptographic package signing the way Linux has.
-
Admin almost 8 years@Wildcard it's just for scripting; not writing entire software packages...
-
Admin almost 8 years@leeand00 A script is a special case of a software package and I can't see any point to singling out that case.
-
Admin almost 8 yearsThe mechanism I'm most fond of is the way ChromeOS does this -- putting the only filesystem not flagged
noexec
on a read-only partition on a dm-verity signed block device. -
Admin almost 8 years@CharlesDuffy okay, you're going to have to unpack that for me Charles...link?
-
Admin almost 8 yearssource.android.com/security/verifiedboot talks about Android's adoption of that (initially ChromeOS) feature.
-
Admin almost 8 yearsYou can consider bash as a bunch of commands that can be typed manual in command line interface. What's the point to restrict the scripts when you can type the contents in command line anyway?
-
Admin almost 8 yearsYou've tagged and mentioned bash, but there are other shells available; is your question specific to bash, or general to any scripting shell in Linux?
-
Admin almost 8 years@JeffSchaller well I was assuming bash but if you have something better let me know about it.
-
Admin over 5 yearsI think this question is pretty vague. Are you wanting a shell that does this on execution, on download through a repository (apt/npm esque), a kernel, a module, or executable format?
-
-
leeand00 almost 8 yearsThe only thing this doesn't present is running a script that somebody just made...on their own...
-
Stephen Harris almost 8 yearsFWIW, on top of this PowerShell can be configured (by policy settings) to only execute signed scripts and this policy can be configured so that all scripts must be signed or only "remote origin" scripts, or no scripts. It works best in an AD environment with key management and central policy management. It can be bypassed :-)
-
leeand00 almost 8 years@StephenHarris Well yeah if you set It to bypass...
-
Stephen Harris almost 8 years@leeand00 - Apparently base64 encoding also works as a bypass but I don't know if that's been closed in newer versions of PowerShell.
-
leeand00 almost 8 years@StephenHarris whoa what?!? Which old version does that?!??
-
alzee almost 8 years
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?
Not allowing executing of any unsigned executables would do it, If the user doesn't have the signing key. There are various *nix projects for this already. -
Stephen Harris almost 8 years@leeand00 - see darkoperator.com/blog/2013/3/5/… for some fun :-) Basically pass the base64 encoded script as a parameter on the command line :-) Easy enough to wrapper!
-
loa_in_ almost 8 yearsSeLinux annotates files with their origin. It's one of its main premises.
-
user394 almost 8 yearsUpvote for direct answer without suggesting a hackey work-around.
-
jmend almost 8 yearsmany archiving programs do not preserve execute bit on contained files .. well, that's kind of a handicap when you actually want to use it for archiving. Fortunately
tar
does preserve the execute bit. -
loa_in_ almost 8 yearsYou have to use
tar -p
source -
loa_in_ almost 8 years
-p, --preserve-permissions, --same-permissions
means extract information about file permissions (default for superuser) -
domen almost 8 yearsNo, you do NOT need -p. I see what the man page says, but it's not what happens.
touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest
- it's executable here, and I'm not root. -
loa_in_ almost 8 yearsI'll try to improve my answer then.
-
leeand00 almost 8 yearsThat'll hold me over until I read about SE Linux and do it right.