LINUXOR.SK ... open source notes ...

Proxy - CA certificate and ssl_crtd cache commands (lab)

category: solutionz · date: 2019-12-31 · updated: 2026-10-03 · author: LALA

Proxy Solution · Config document · referenced from Squid with SSL interception, Certificate renewal and SELinux and client trust

noteThe answers in the CSR dialogue (<COUNTRY>, Lab) are placeholders for this write-up, not what was typed. The chown -R squid:squid /var/lib/ssl_db/* line changes the owner of the files inside the cache and, as I read it, leaves the directory itself to root; the notes do not remark on it and nothing in them shows it mattered. The lab note records no successful request through Squid: the pip test fails, the export REQUESTS_CA_BUNDLE is recorded as the solution with no second run, so whether it worked is implied by the step title and nothing else.

The command set that gave the lab proxy proxy.lab.example.net its self-signed certificate, installed Squid, created the ssl_crtd certificate cache and placed the proxy's certificate into the system's trust anchors so that the lab host itself trusted the certificates the proxy generates. This certificate is the one the http_port … ssl-bump line of the lab squid.conf points at.

ItemValue
Hostproxy.lab.example.net, RHEL 7.5, VMware guest
Run asroot; the key, CSR and signing steps in /etc/pki/tls/private/, the rest from a directory the notes do not record
Private key/etc/pki/tls/private/proxy.lab.example.net.key, RSA 2048
CSR/etc/pki/tls/private/proxy.lab.example.net.csr
Certificate/etc/pki/tls/certs/proxy.lab.example.net.crt, self-signed, 3652 days
Certificate cache/var/lib/ssl_db, created with ssl_crtd -c -s, files owned by squid:squid
Trust anchora copy of the certificate in /etc/pki/ca-trust/source/anchors/, taken up by update-ca-trust
SoftwareSquid 3.5 (the RHEL 7.5 package, squid-3.5.20-12.el7; the notes print no version), installed with yum install squid; the notes do not print the OpenSSL version either

The commands

Generate the private key. As root on proxy.lab.example.net, in the system directory for private keys.

bash
$ cd /etc/pki/tls/private/
$ openssl genrsa -out proxy.lab.example.net.key 2048

Create the certificate signing request from that key. Same directory; openssl req asks for the distinguished name interactively, the answers follow in the output block (the notes do not keep the preamble that openssl req prints before the first question). The organisation, unit, email address, challenge password and optional company name were left empty.

bash
$ openssl req -new -key proxy.lab.example.net.key -out proxy.lab.example.net.csr
output 12 lines
Country Name (2 letter code) [XX]:<COUNTRY>
State or Province Name (full name) []:None
Locality Name (eg, city) [Default City]:Lab
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:proxy.lab.example.net
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Sign the request with its own key, which makes a self-signed certificate valid for 3652 days, and move the certificate to the system directory for certificates. Same directory.

bash
$ openssl x509 -req -days 3652 -in proxy.lab.example.net.csr -signkey proxy.lab.example.net.key -out proxy.lab.example.net.crt
$ mv proxy.lab.example.net.crt /etc/pki/tls/certs/

Install Squid, create the certificate cache that ssl_crtd will fill with the generated host certificates, and hand its files to the squid user. As root; the notes do not say from which directory.

bash
$ yum install squid
$ /usr/lib64/squid/ssl_crtd -c -s /var/lib/ssl_db
$ chown -R squid:squid /var/lib/ssl_db/*

Place the proxy's certificate into the system's trust anchors and rebuild the bundle. The notes title this step "Place proxy CA certificate to system anchors" and list it among the steps on the lab proxy; the pip test of the pip test commands relies on a bundle built this way, and the notes do not say on which host that test ran. As root.

bash
$ cp /etc/pki/tls/certs/proxy.lab.example.net.crt /etc/pki/ca-trust/source/anchors/
$ update-ca-trust

What the lines mean

LineMeaning
openssl genrsa -out … 2048a 2048-bit RSA private key, unencrypted (no -aes256 or similar), so Squid can read it without a passphrase
openssl req -new -key … -out ….csra certificate signing request for that key; the only answer that matters to Squid is the Common Name proxy.lab.example.net, the rest was left at nothing
openssl x509 -req -days 3652 -in ….csr -signkey ….key -out ….crtsigns the request with the same key: a self-signed certificate, ten years and two days long. No -extensions or -extfile, so, as I understand openssl x509, the result is an X.509 version 1 certificate with no basicConstraints; Squid used it as the signing certificate for the generated host certificates all the same
/usr/lib64/squid/ssl_crtd -c -s /var/lib/ssl_db-c creates (initialises) the certificate database at the path given with -s; Squid's ssl_crtd helper later stores the host certificates it generates there
chown -R squid:squid /var/lib/ssl_db/*the helper runs as the squid user and must write into the database; the glob changes the owner of what is inside the directory, not of /var/lib/ssl_db itself (my reading, see the NOTE)
cp ….crt /etc/pki/ca-trust/source/anchors/ and update-ca-trustthe RHEL way to add a CA to the system bundle: anything in anchors/ is merged into /etc/pki/tls/certs/ca-bundle.crt and the other generated bundles

On the production proxies the files live in /etc/ssl/squid/ with a _1 or _2 in the names and the certificate has a 365-day validity and is renewed by hand when it runs out (the notes hold one renewal per host); that command set is in certificate renewal on dc1-a-vcprx001 and certificate renewal on dc2-a-vcprx001. The production notes do not show the first creation of the key, only the renewal from the existing key.

Checked against OpenSSL 3.5, Squid 7.7 and ca-certificates 2026.2.90

As builtToday
openssl genrsa -out … 2048Still a valid command; the genrsa man page gives 2048 as the default and marks nothing about it as superseded
openssl x509 -req -days 3652 -signkey …-signkey was renamed -key in OpenSSL 3.0 and is kept as an alias; -days still defaults to 30; since OpenSSL 3.2 x509 emits X.509 version 3 certificates with key identifier extensions. Without -extfile or -extensions the result still has no basicConstraints, so it is still not a CA certificate
A two-step CSR and self-signingThe Squid wiki's one-step recipe is openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -extensions v3_ca …; with the stock openssl.cnf ([ req ] x509_extensions = v3_ca, basicConstraints = critical,CA:true) req -x509 yields a CA certificate even without -extensions v3_ca. -nodes is deprecated since OpenSSL 3.0 in favour of -noenc
A signing certificate without basicConstraintsSquid 7.7 documents that with generate-host-certificates=on "the first tls-cert= option must be a CA certificate capable of signing the automatically generated certificates"
/usr/lib64/squid/ssl_crtd -c -s /var/lib/ssl_dbRenamed in Squid 4 to security_file_certgen, on RHEL 9 and 10 /usr/lib64/squid/security_file_certgen; its compiled-in default database moved to /var/spool/squid/ssl_db on RHEL builds; -s now requires -M, so the initialisation is security_file_certgen -c -s DIR -M 4MB
chown -R squid:squid /var/lib/ssl_db/*The Squid wiki says to make "the directory writable for the squid user" after initialising the database; the glob leaves the directory itself to root
cp … /etc/pki/ca-trust/source/anchors/ and update-ca-trustUnchanged: the update-ca-trust man page still gives exactly this as its first quick help, and /etc/pki/tls/certs/ca-bundle.crt is still a symlink to /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem in the current ca-certificates package

The commands still run, but the certificate they make is the wrong kind for a current Squid: the two-step x509 -req path produces a certificate that is not a CA, and Squid 7.7 requires one that is. The Squid wiki's one-step req -x509 recipe with the stock configuration is the documented way today. The helper and its default path were renamed and moved, and the -M size became mandatory.

← solutionz