240 lines
6.2 KiB
Markdown
240 lines
6.2 KiB
Markdown
# OpenSSL Command Reference for Self-Signed Certificate Generation
|
||
|
||
This document explains the OpenSSL command-line tool and provides a structured, DevOps-friendly guide for generating self-signed SSL/TLS certificates. These certificates are commonly used for internal services, development environments, testing, or private infrastructure components such as Gitea, Jenkins, internal APIs, or Kubernetes ingress controllers.
|
||
|
||
---
|
||
|
||
## 1. What is OpenSSL?
|
||
|
||
**OpenSSL** is a widely used, open-source cryptographic toolkit that implements the SSL and TLS protocols. It provides utilities for:
|
||
|
||
* Generating private and public key pairs
|
||
* Creating Certificate Signing Requests (CSRs)
|
||
* Issuing and managing X.509 certificates
|
||
* Encrypting and decrypting data
|
||
* Inspecting and troubleshooting TLS connections
|
||
|
||
OpenSSL is available on most Linux distributions by default and is commonly used in DevOps and SRE workflows.
|
||
|
||
Check installed version:
|
||
|
||
```bash
|
||
openssl version
|
||
```
|
||
|
||
---
|
||
|
||
## 2. When to Use Self-Signed Certificates
|
||
|
||
Self-signed certificates are suitable for:
|
||
|
||
* Internal services
|
||
* Development and staging environments
|
||
* Private networks
|
||
* Lab and proof-of-concept setups
|
||
|
||
They are **not recommended for public-facing production systems**, because they are not trusted by browsers or external clients without manual trust configuration.
|
||
|
||
---
|
||
|
||
## 3. Generating a Self-Signed Certificate (Example: Gitea)
|
||
|
||
This process consists of three logical steps:
|
||
|
||
1. Generate a private key
|
||
2. Create a Certificate Signing Request (CSR)
|
||
3. Sign the CSR using the same key to produce a self-signed certificate
|
||
|
||
---
|
||
|
||
## 4. Step 1: Generate a Private Key
|
||
|
||
Generate a 2048-bit RSA private key:
|
||
|
||
```bash
|
||
openssl genrsa -out gitea.key 2048
|
||
```
|
||
|
||
### Explanation
|
||
|
||
| Component | Description |
|
||
| ---------------- | -------------------------------------------------- |
|
||
| `genrsa` | Generates an RSA private key |
|
||
| `-out gitea.key` | Output file for the private key |
|
||
| `2048` | Key size in bits (2048 is the recommended minimum) |
|
||
|
||
Security note:
|
||
|
||
* The private key must be kept secret
|
||
* Restrict file permissions:
|
||
|
||
```bash
|
||
chmod 600 gitea.key
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Step 2: Create a Certificate Signing Request (CSR)
|
||
|
||
Generate a CSR using the private key:
|
||
|
||
```bash
|
||
openssl req -new -key gitea.key -out gitea.csr
|
||
```
|
||
|
||
### Explanation
|
||
|
||
| Component | Description |
|
||
| ---------------- | ---------------------------------------- |
|
||
| `req` | Certificate request management command |
|
||
| `-new` | Creates a new CSR |
|
||
| `-key gitea.key` | Private key used to generate the request |
|
||
| `-out gitea.csr` | Output file for the CSR |
|
||
|
||
### Interactive Fields
|
||
|
||
During execution, OpenSSL prompts for certificate metadata:
|
||
|
||
* Country Name (C)
|
||
* State or Province (ST)
|
||
* Locality (L)
|
||
* Organization (O)
|
||
* Organizational Unit (OU)
|
||
* **Common Name (CN)**
|
||
|
||
Important:
|
||
|
||
* The **Common Name (CN)** should match the service hostname or domain name
|
||
Example:
|
||
|
||
```
|
||
gitea.example.com
|
||
```
|
||
|
||
For automation or CI/CD pipelines, this step can be made non-interactive (see section 8).
|
||
|
||
---
|
||
|
||
## 6. Step 3: Create the Self-Signed Certificate
|
||
|
||
Sign the CSR using the same private key:
|
||
|
||
```bash
|
||
openssl x509 -req -in gitea.csr -signkey gitea.key -out gitea.crt
|
||
```
|
||
|
||
### Explanation
|
||
|
||
| Component | Description |
|
||
| -------------------- | ------------------------------------------ |
|
||
| `x509` | X.509 certificate management |
|
||
| `-req` | Indicates the input is a CSR |
|
||
| `-in gitea.csr` | Input CSR file |
|
||
| `-signkey gitea.key` | Signs the certificate with the private key |
|
||
| `-out gitea.crt` | Output certificate file |
|
||
|
||
Default behavior:
|
||
|
||
* Certificate is valid immediately
|
||
* Validity is typically 30 days unless specified
|
||
|
||
To set validity explicitly (example: 365 days):
|
||
|
||
```bash
|
||
openssl x509 -req -days 365 -in gitea.csr -signkey gitea.key -out gitea.crt
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Verify the Certificate
|
||
|
||
Inspect certificate details:
|
||
|
||
```bash
|
||
openssl x509 -in gitea.crt -text -noout
|
||
```
|
||
|
||
Verify key and certificate match:
|
||
|
||
```bash
|
||
openssl rsa -noout -modulus -in gitea.key | openssl md5
|
||
openssl x509 -noout -modulus -in gitea.crt | openssl md5
|
||
```
|
||
|
||
Matching hashes confirm correctness.
|
||
|
||
---
|
||
|
||
## 8. Non-Interactive Certificate Generation (Recommended for Automation)
|
||
|
||
Generate key and certificate in one command:
|
||
|
||
```bash
|
||
openssl req -x509 -newkey rsa:2048 \
|
||
-keyout gitea.key \
|
||
-out gitea.crt \
|
||
-days 365 \
|
||
-nodes \
|
||
-subj "/C=US/ST=State/L=City/O=Company/OU=DevOps/CN=gitea.example.com"
|
||
```
|
||
|
||
Options explained:
|
||
|
||
* `-x509`: Generate a self-signed certificate
|
||
* `-newkey`: Create a new private key
|
||
* `-nodes`: Do not encrypt the private key (required for services)
|
||
* `-subj`: Certificate subject (non-interactive)
|
||
|
||
This approach is ideal for:
|
||
|
||
* CI/CD pipelines
|
||
* Docker images
|
||
* Infrastructure as Code workflows
|
||
|
||
---
|
||
|
||
## 9. Subject Alternative Name (SAN) Consideration
|
||
|
||
Modern TLS clients require **SAN** instead of CN.
|
||
|
||
Example OpenSSL config snippet:
|
||
|
||
```
|
||
subjectAltName = DNS:gitea.example.com,DNS:gitea.internal
|
||
```
|
||
|
||
Without SAN:
|
||
|
||
* Browsers may reject the certificate
|
||
* TLS warnings may appear even if CN matches
|
||
|
||
---
|
||
|
||
## 10. Summary of Generated Files
|
||
|
||
| File | Description |
|
||
| ----------- | ---------------------------------------------------- |
|
||
| `gitea.key` | Private key (keep secure, server-side only) |
|
||
| `gitea.csr` | Certificate Signing Request (optional after signing) |
|
||
| `gitea.crt` | Self-signed certificate presented to clients |
|
||
|
||
---
|
||
|
||
## 11. Best Practices
|
||
|
||
* Never commit private keys to Git
|
||
* Store secrets securely (Vault, SSM, Kubernetes secrets)
|
||
* Rotate certificates regularly
|
||
* Use Let’s Encrypt or internal CA for production
|
||
* Prefer SAN over CN
|
||
* Automate certificate generation where possible
|
||
|
||
---
|
||
|
||
If you want, I can:
|
||
|
||
* Add an OpenSSL SAN configuration example
|
||
* Provide Kubernetes, Nginx, or Gitea-specific TLS configs
|
||
* Convert this into a reusable internal PKI guide
|
||
* Add troubleshooting and common TLS errors
|