I'm adding HTTPS support to an embedded Linux device. I have tried to generate a self-signed certificate with these steps:
openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem
This works, but I get some errors with, for example, Google Chrome:
This is probably not the site you are looking for!
The site's security certificate is not trusted!
Am I missing something? Is this the correct way to build a self-signed certificate?
One-liner version 2017:
CentOS:
Ubuntu:
You can do that in one command:
You can also add
-nodes
(short forno DES
) if you don't want to protect your private key with a passphrase. Otherwise it will prompt you for "at least a 4 character" password.The
days
parameter (365) you can replace with any number to affect the expiration date. It will then prompt you for things like "Country Name", but you can just hit Enter and accept the defaults.Add
-subj '/CN=localhost'
to suppress questions about the contents of the certificate (replacelocalhost
with your desired domain).Self-signed certificates are not validated with any third party unless you import them to the browsers previously. If you need more security, you should use a certificate signed by a certificate authority (CA).
Here are the options described in @diegows's answer, described in more detail, from the documentation:
The documentation is actually more detailed than the above; I just summarized it here.
On my setup, Ubuntu server logged to:
/var/log/mysql/error.log
Follow up notes:
SSL error: Unable to get certificate from '...'
MySQL might be denied read access to your certificate file if it is not in apparmors configuration. As mentioned in the previous steps^, save all our certificates as
.pem
files in the/etc/mysql/
directory which is approved by default by apparmor (or modify your apparmor/SELinux to allow access to wherever you stored them.)SSL error: Unable to get private key
Your MySQL server version may not support the default
rsa:2048
formatConvert generated
rsa:2048
to plainrsa
with:Check if local server supports SSL:
Verifying a connection to the database is SSL encrypted:
Require ssl for specific user's connection ('require ssl'):
Alternate link: Lengthy tutorial in Secure PHP Connections to MySQL with SSL.
You have the general procedure correct. The syntax for the command is below.
However, the warnings are displayed, because the browser was not able to verify the identify by validating the certificate with a known Certificate Authority (CA).
As this is a self-signed certificate there is no CA and you can safely ignore the warning and proceed. Should you want to get a real certificate that will be recognizable by anyone on the public Internet then the procedure is below.
I have more details about this in a post at Securing the Connection: Creating a Security Certificate with OpenSSL
As of 2018, the following command serves all your needs, including SAN:
In OpenSSL ≥ 1.1.1, this can be shortened to:
It creates a certificate that is
example.com
andexample.net
(SAN),10.0.0.1
(SAN),3650
days (~10 years).It creates the following files:
example.key
example.crt
All information is provided at the command line. There is no annoying interactive input. There is no messing around with config files. All necessary steps are executed by this single OpenSSL invocation: from private key generation up to the self-signed certificate.
Since the certificate is self-signed and needs to be accepted by users manually, it doesn't make sense to use a short expiration or weak cryptography.
In the future, you might want to use more than
4096
bits for the RSA key and a hash algorithm stronger thansha256
, but as of 2018 these are sane values. They are sufficiently strong while being supported by all modern browsers.Remark #1: Parameter "nodes"
Theoretically you could leave out the
-nodes
parameter (which means "no DES encryption"), in which caseexample.key
would be encrypted with a password. However, this is almost never useful for a server installation, because you would either have to store the password on the server as well, or you'd have to enter it manually on each reboot.Remark #2: MinGW
On Windows / MinGW, you should prefix the command with
MSYS_NO_PATHCONV=1
:Alternatively, run the command in the plain
cmd.exe
Windows command prompt.Remark #3: See also