Is there a shell that checks to make sure the code is signed?

5,496

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 "$@"
Share:
5,496

Related videos on Youtube

leeand00
Author by

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, 2022

Comments

  • leeand00
    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
      Admin almost 8 years
      Sounds 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
      Admin almost 8 years
      @Wildcard it's just for scripting; not writing entire software packages...
    • Admin
      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
      Admin almost 8 years
      The 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
      Admin almost 8 years
      @CharlesDuffy okay, you're going to have to unpack that for me Charles...link?
    • Admin
      Admin almost 8 years
      source.android.com/security/verifiedboot talks about Android's adoption of that (initially ChromeOS) feature.
    • Admin
      Admin almost 8 years
      You 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
      Admin almost 8 years
      You'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
      Admin almost 8 years
      @JeffSchaller well I was assuming bash but if you have something better let me know about it.
    • Admin
      Admin over 5 years
      I 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
    leeand00 almost 8 years
    The only thing this doesn't present is running a script that somebody just made...on their own...
  • Stephen Harris
    Stephen Harris almost 8 years
    FWIW, 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
    leeand00 almost 8 years
    @StephenHarris Well yeah if you set It to bypass...
  • Stephen Harris
    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
    leeand00 almost 8 years
    @StephenHarris whoa what?!? Which old version does that?!??
  • alzee
    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
    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_
    loa_in_ almost 8 years
    SeLinux annotates files with their origin. It's one of its main premises.
  • user394
    user394 almost 8 years
    Upvote for direct answer without suggesting a hackey work-around.
  • jmend
    jmend almost 8 years
    many 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_
    loa_in_ almost 8 years
    You have to use tar -p source
  • loa_in_
    loa_in_ almost 8 years
    -p, --preserve-permissions, --same-permissions means extract information about file permissions (default for superuser)
  • domen
    domen almost 8 years
    No, 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_
    loa_in_ almost 8 years
    I'll try to improve my answer then.
  • leeand00
    leeand00 almost 8 years
    That'll hold me over until I read about SE Linux and do it right.