Bash Script working on Tumbleweed but not Kubuntu - bash

We have a virtual Dev-Environment in which we develop a multitude of websites.
We have some scripts that we use to create the environment, one of which handles the creation of the Certificates and pushing them to certain directories.
Said script works for my colleague, who uses Tumbleweed, but not for me (Kubuntu 22.04, Kernel 5.15)
The script is the following:
#!/bin/bash
mkdir -p cert/live/exist.ulb.tu-darmstadt.de
mkdir -p cert/live/purl.ulb.tu-darmstadt.de
mkdir -p cert/live/tueditions.ulb.tu-darmstadt.de
cd cert
openssl req \
-x509 \
-nodes \
-new \
-sha256 \
-days 1024 \
-newkey rsa:2048 \
-keyout ${CertAUTH}.key \
-out ${CertAUTH}.pem \
-subj "/C=DE/CN=Example-Root-CA"
openssl x509 \
-outform pem \
-in ${CertAUTH}.pem \
-out ${CertAUTH}.crt
openssl req \
-outform pem \
-new \
-nodes \
-newkey rsa:2048 \
-keyout privkey.pem \
-out localhost.csr \
-subj "/C=DE/ST=HE/L=Darmstadt/O=ULB/CN=*.localhost"
openssl x509 \
-outform pem \
-req \
-sha256 \
-days 1024 \
-in localhost.csr \
-CA ${CertAUTH}.pem \
-CAkey ${CertAUTH}.key \
-CAcreateserial \
-extfile domains.ext \
-out fullchain.pem
cp fullchain.pem live/exist.ulb.tu-darmstadt.de
cp fullchain.pem live/purl.ulb.tu-darmstadt.de
cp fullchain.pem live/tueditions.ulb.tu-darmstadt.de
cp privkey.pem live/exist.ulb.tu-darmstadt.de
cp privkey.pem live/purl.ulb.tu-darmstadt.de
cp privkey.pem live/tueditions.ulb.tu-darmstadt.de
cd ..
The script is supposed to create directories and create fullchain.pem files, yyou can probably get what it should do.My output is the following:
Can't open "domains.ext" for reading, No such file or directory
4047A01AD37F0000:error:80000002:system library:BIO_new_file:No such file or directory:../crypto/bio/bss_file.c:67:calling fopen(domains.ext, r)
4047A01AD37F0000:error:10000080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:75:
cp: Aufruf von stat für 'fullchain.pem' nicht möglich: Datei oder Verzeichnis nicht gefunden
cp: Aufruf von stat für 'fullchain.pem' nicht möglich: Datei oder Verzeichnis nicht gefunden
cp: Aufruf von stat für 'fullchain.pem' nicht möglich: Datei oder Verzeichnis nicht gefunden
nota bene: we have pre-created the domains.ext as current user and entered the necessary information.We're clueless what's happening here, maybe somebody here has a solution for me/us?
all the best

The cp errors are because the script didn't exit after failing the create the previous dependency. Add set -e -o pipefail the top to prevent the script from proceeding after an error.
Next, the domains.ext isn't in the correct location. At the top, your allowing mkdir to fail silently with the -p argument:
-p, --parents
no error if existing, make parent directories as needed
Meaning that it likely created the cert dir too, which is where your script was expecting to find the domains.ext. You can confirm this by testing for your prerequsits first, exiting with a sane failure if it's missing. This is what I would add to the top of the file:
#!/usr/bin/env bash
set -e -o pipefail
[[ -f cert/domains.ext ]] || { echo 'ERROR: ./cert/domains.ext is missing' ; exit 1 ; }

Related

Shell-script to decrypt file

I have to create a shell-script that can decrypt a RSA key file that is encrypted with a specific .pem file. And then to decrypt zip file with the AES key which I get from the RSA file once it is decrypted in a file named keyaes (or whatever you want).
Here are the two commands I have to use
openssl rsautl -decrypt -in AES_KEY -inkey CERTIFICATE.pem -out keyaes
openssl enc -d -aes-256-cbc -in zipfile.zip -out extraction.zip -nosalt -p -K RSA_KEY_from_key_aes_output -iv 0
The commands work perfectly, the problem is in my script I don't know how to make it automatically and to get the key from the keyaes output and put it into the next command properly.
How can I do it ?
you could just use bash command substitution in the second command, using backticks
openssl enc -d -aes-256-cbc -in zipfile.zip -out extraction.zip -nosalt -p -K `cat output_filename_with_aes_key` -iv 0

Syntax error: "(" unexpected error while creating an openssl certificate using a bash command

Using the instructions over here to define the SAN field inside the a openssl certificate, I am using the following commands to generate my own self-signed certificate:
openssl genrsa -out domain.org.key
openssl req -newkey rsa:2048 -nodes -keyout domain.org.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=*.domain.org" -out domain.org.csr
openssl x509 -req -extfile <(printf "subjectAltName=DNS:domain.org,DNS:www.domain.org") -days 365 -in domain.org.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out domain.org.crt
However, I am getting the following error:
Syntax error: "(" unexpected
I don't see anything specifically wrong with the bash syntax used, could anyone help?
That error-message doesn't look like Bash to me; rather, Bash error-messages look like this:
bash: syntax error near unexpected token `('
I recommend double-checking that you're running these commands in Bash, and not a different shell. (Process substitution isn't specified by POSIX, so not all shells support it.)
If it turns out that Bash is not available, you can use a temporary file:
printf "subjectAltName=DNS:domain.org,DNS:www.domain.org" > tmp-ext-file
openssl x509 -req -extfile tmp-ext-file -days 365 -in domain.org.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out domain.org.crt
or standard input:
printf "subjectAltName=DNS:domain.org,DNS:www.domain.org" \
| openssl x509 -req -extfile /dev/stdin -days 365 -in domain.org.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out domain.org.crt

How to combine the two commands into one with pipe?

Package directroy $HOME/Desktop/bill into /tmp/bill.tar and encrypt it with key into /tmp/bill.asc.
key="xxxxxxxx"
tar -zcP $HOME/Desktop/bill -f /tmp/bill.tar
openssl enc -des3 -a -salt -in /tmp/bill.tar -k ${key} -out /tmp/bill.asc
I want to combine tar and openssl as one whole command with pipe.
tar -zcP $HOME/Desktop/bill -f | openssl enc -des3 -a -salt -in -k ${key} -out /tmp/bill.asc
It can't work,how to fix it?
Without -f parameter,remove -in parameter in Bsquare's post.
tar -zcP $HOME/Desktop/bill |openssl enc -des3 -a -salt -k ${key} -out /tmp/bill.asc
With -f parameter,same as John Law say.
tar -zcP $HOME/Desktop/bill -f /tmp/bill.tar | openssl enc -des3 -a -salt -k ${key} -out /tmp/bill.asc

Shell: Capturing output files in variables

Commands like openssl have arguments like -out <file> for output files. I'd like to capture the content of these output files in shell variables for use in other commands without creating temporary files. For example, to generate a self-signed certificate, one can use:
openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 -keyout KEYFILE -out CERTFILE 2>/dev/null
The closest I've got to capture both output files is to echo them to stdout via process substitution but this is not ideal because one would still have to parse them apart.
openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 -keyout >(key=$(cat -); echo $key) -out >(cert=$(cat -); echo $cert) 2>/dev/null
Is there a clean way to capture the content of output files in shell variables?
Most modern shells now support /dev/stdout as a file name to redirect to stdout. This is good enough for single file solutions but for two output files you need to go with "process substitution".
eval "$( openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 -keyout >(echo "keyout='$( cat )'" ) -out >(echo out="'$( cat )'" ) )"
This uses process substitution to direct each "file" to a separate process that prints to stdout an assignment of the calculated values. The whole thing is then passed to an eval to do the actual assignments.
Keeping output of stderr to show any error messages that pops up. Useful to log it in times of troubles.
Edit: incorporating Charles Duffy's good paranoia:
flockf="$(mktemp -t tmp.lock.$$.XXXXXX )" || exit $?;
eval "$( openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 \
-keyout >( set -x; 99>"$flockf" && \
flock -x "$flockf" printf "keyout=%q " "$( cat )"; ) \
-out >( set -x; 99>"$flockf" && \
flock -x "$flockf" printf "out=%q " "$( cat )"; ) \
)" ;
rm -f "$flockf"
An extension to Gilbert's answer providing additional paranoia:
eval "$( openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 \
-keyout >(printf 'keyout=%q\n' "$(</dev/stdin)") \
-out >(printf 'out=%q\n' "$(</dev/stdin)") )"
(Note that this is not suitable if your data contains NULs, which bash cannot store in a native shell variable; in that case, you'll want to assign the contents to your variables in base64-encoded form).
Unlike echo "keyout='$(cat)'", printf 'keyout=%q\n' "$(cat)" ensures that even malicious contents cannot be evaluated by the shell as a command substitution, redirection, or otherwise content other than literal data.
To explain why this is necessary, let's take a simplified case:
write_to_two_files() { printf 'one\n' >"$1"; printf 'two\n' >"$2"; }
write_to_two_files >(echo "one='$(cat)'") >(echo "two='$(cat)'")
...we get output akin to (but with no particular ordering):
two='two'
one='one'
...which, when evaled, sets two variables:
$ eval "$(write_to_two_files >(echo "one='$(cat)'") >(echo "two='$(cat)'"))"
$ declare -p one two
declare -- one="one"
declare -- two="two"
However, let's say that our program behaves a bit differently:
## Demonstrate why eval'ing content created by echoing data is dangerous
write_to_two_files() {
printf "'%s'\n" '$(touch /tmp/i-pwned-your-box)' >"$1"
echo "two" >"$2"
}
eval "$(write_to_two_files >(echo "one='$(cat)'") >(echo "two='$(cat)'"))"
ls -l /tmp/i-pwned-your-box
Instead of merely assigning the output to a variable, we evaluated it as code.
If you're further interested in ensuring that the two print operations happen at different times (preventing their output from being intermingled), it's useful to further add locking. This does involve a temporary file, but does not write your keying material to disk (avoidance of which is the most compelling reason to avoid temporary file usage):
lockfile=$(mktemp -t output.lck.XXXXXX)
eval "$( openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 \
-keyout >(in=$(cat); exec 99>"$lockfile" && flock -x 99 && printf 'keyout=%q\n' "$in") \
-out >(in=$(cat); exec 99>"$lockfile" && flock -x 99 && printf 'out=%q\n' "$in") )"
Note that we're only blocking for the write, not the read, so we can't get into race conditions (ie. where openssl isn't finishing writing to file-A because it's blocked on a write to file-B, which can never complete because the subshell on the read side of the file-A write holds the lock).

Openssl: cat: /dev/fd/63: No such file or directory

I try to create a Certificate Signing Request (CSR) using
openssl req -new -sha256 -key domain.key -subj "/" \ -reqexts SAN -config <(cat /System/Library/OpenSSL/openssl.cnf \ <(printf "[SAN]\nsubjectAltName=DNS:foo.com,DNS:www.foo.com"))
but getting the following error message on my macbook
cat: /dev/fd/63: No such file or directory
unknown option -reqexts
Any ideas?
Your command is probably copy&paste of a multi-line command where backslashes are used to join lines, however you somehow managed to get newlines converted to spaces.
Remove all occurences of "backslash + space".
I came across this question and in my case I did not have any \ , but I was using sudo so I had to use sudo su -c
$ sudo su -c 'openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-blah.blah.com.key -new -out /etc/ssl/certs/nginx-blah.blah.com.crt -subj "/O=blah.com/OU=blah/CN=blah.blah.com" -reqexts SAN -extensions SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:blah.blah.com,IP:192.168.174.128")) -sha256'
In some cases not mounted devpts can lead to the same error print. So needed to do:
mount -t devpts devpts /dev/pts

Resources