Compare commits

...

4 Commits

Author SHA1 Message Date
RadinPirouz
1b25ca1081 date: added to doc 2026-01-19 14:27:36 +03:30
RadinPirouz
006ea9a79f diff: cleaned doc 2026-01-19 14:27:21 +03:30
RadinPirouz
4093ac50ad openssl: update and cleaned 2026-01-19 14:23:50 +03:30
RadinPirouz
9cbf903552 git doc: updated and cleaned 2026-01-19 14:21:44 +03:30
4 changed files with 972 additions and 125 deletions

View File

@@ -1,215 +1,523 @@
# Git Commands Guide
# Git Commands Guide (DevOps-Oriented)
## 1. Installation and Setup
### Install Git
Download from [git-scm.com](https://git-scm.com/).
Download and install Git from:
[https://git-scm.com/](https://git-scm.com/)
Linux (Debian/Ubuntu):
```bash
sudo apt update && sudo apt install git -y
```
RHEL/CentOS:
```bash
sudo yum install git -y
```
macOS (Homebrew):
```bash
brew install git
```
### Verify Installation
```bash
git --version
```
### Configure User Info
Set your name and email for commits:
### Configure User Identity
Git uses this information for commits:
```bash
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
```
Check configuration:
```bash
git config --list
```
Configuration scopes:
* `--system`: All users
* `--global`: Current user
* `--local`: Repository only
---
## 2. SSH Key Configuration
Use a custom SSH key:
### Generate SSH Key
```bash
git config --add --local core.sshCommand 'ssh -i <PATH_TO_SSH_KEY>'
ssh-keygen -t ed25519 -C "your.email@example.com"
```
Clone with custom key:
Start SSH agent and add key:
```bash
git -c core.sshCommand="ssh -i <key-path>" clone host:repo
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
```
### Use Custom SSH Key (Per Repository)
```bash
git config --local core.sshCommand "ssh -i <PATH_TO_SSH_KEY>"
```
Clone with custom SSH key:
```bash
git -c core.sshCommand="ssh -i <key-path>" clone git@host:repo.git
```
---
## 3. Initialize Repository
Create a new Git repo:
Create a new Git repository:
```bash
git init -b main
```
- `-b main`: Sets default branch name to `main`.
Existing repository:
```bash
git init
```
---
## 4. Basic Workflow
### Stage and Commit
### Stage and Commit Changes
Stage all changes:
```bash
git add -A
```
Commit changes:
```bash
git commit -m "Initial Commit"
git commit -m "Initial commit"
```
### Connect to Remote
Link local repo to remote:
### Connect Local Repository to Remote
```bash
git remote add origin <Repo-Link>
git remote add origin <REPO_URL>
```
Verify:
```bash
git remote -v
```
### Push to Remote
First push:
```bash
git push origin main
git push -u origin main
```
Subsequent pushes:
```bash
git push
```
---
## 5. Repository Status and History
### Check Status
### Check Repository Status
```bash
git status
```
Shows staged, unstaged, and untracked files.
### View History
### View Commit History
```bash
git log
```
- `git log -p`: Shows diffs per commit.
- `git log -3`: Shows last 3 commits.
- `git log --graph`: Shows history as a graph.
- `git log --oneline`: Shows compact log.
### View Changes
Common options:
```bash
git log --oneline
git log --graph --oneline --all
git log -p
git log -3
```
### View File Changes
Unstaged changes:
```bash
git diff
```
Shows unstaged changes.
Staged changes:
```bash
git diff --staged
```
Shows staged changes.
Compare branches:
```bash
git diff main..dev
```
---
## 6. File Operations
### Stage Specific Files
```bash
git add <filename>
git add <file>
```
### Unstage Files
```bash
git reset <filename>
git reset <file>
```
### Discard Changes
### Discard Local Changes
```bash
git checkout -- <filename>
git checkout -- <file>
```
Restore using modern command:
```bash
git restore <file>
```
Reverts file to last committed state.
### Rename File
```bash
git mv <old-name> <new-name>
git mv old-name new-name
```
### Remove File
```bash
git rm <filename>
git rm <file>
```
Remove but keep locally:
```bash
git rm --cached <file>
```
---
## 7. Branch Management
### Create and Switch to Branch
### Create and Switch Branch
```bash
git checkout -b <branch-name>
```
Modern alternative:
```bash
git switch -c <branch-name>
```
### List Branches
```bash
git branch
```
List with details:
```bash
git branch -a
git branch -v
```
### Delete Branch
```bash
git branch -d <branch-name>
```
### Switch Branch
Force delete:
```bash
git checkout <branch-name>
git branch -D <branch-name>
```
## 8. Merging
### Rename Branch
```bash
git branch -m old-name new-name
```
---
## 8. Merging and Rebasing
### Merge Branch
```bash
git merge <branch-name>
```
**Merge Types:**
- **Fast-forward:** No conflicts; branch is ahead of target.
- **Three-way:** Conflicts possible; creates new merge commit.
Merge types:
* Fast-forward
* Three-way merge (creates merge commit)
### Rebase (Linear History)
```bash
git rebase main
```
Abort rebase:
```bash
git rebase --abort
```
Continue rebase:
```bash
git rebase --continue
```
---
## 9. Remote Operations
### List Remotes
```bash
git remote
```
### Show Remote Info
```bash
git remote -v
```
### Show Remote Details
```bash
git remote show origin
```
### Fetch Changes
```bash
git fetch
```
Get updates without merging.
```bash
git fetch
git fetch --all
```
Fetch from all remotes.
### Pull Changes
Fetch + merge:
```bash
git pull
```
Rebase instead of merge:
```bash
git pull --rebase
```
---
## 10. Commit Management
### Edit Last Commit Message
### Amend Last Commit
```bash
git commit --amend
```
### Show Commit Changes
### Show Commit Details
```bash
git show <commit-id>
```
### Revert Commit
```bash
git revert HEAD
```
Revert last commit.
### Revert Commit (Safe for Shared Branches)
```bash
git revert <commit-id>
```
Revert specific commit.
## 11. Miscellaneous
### Reset Commit (Use with Caution)
Soft reset:
```bash
git reset --soft HEAD~1
```
Mixed reset:
```bash
git reset HEAD~1
```
Hard reset:
```bash
git reset --hard HEAD~1
```
---
## 11. Stash (Temporary Changes)
Save work without committing:
```bash
git stash
```
List stashes:
```bash
git stash list
```
Apply stash:
```bash
git stash apply
```
Pop stash:
```bash
git stash pop
```
---
## 12. Tags (Releases)
Create tag:
```bash
git tag v1.0.0
```
Annotated tag:
```bash
git tag -a v1.0.0 -m "Release v1.0.0"
```
Push tags:
```bash
git push origin --tags
```
---
## 13. .gitignore
Create `.gitignore`:
```bash
touch .gitignore
```
Example:
```
.env
node_modules/
*.log
```
Apply after commit:
```bash
git rm -r --cached .
git add .
git commit -m "Apply gitignore"
```
---
## 14. Useful Configuration and Aliases
Change default editor:
### Change Default Editor
```bash
git config --global core.editor "vim"
```
### Clone Repository
Create aliases:
```bash
git clone <Repo-Link>
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.cm commit
git config --global alias.br branch
```
---
## 15. Troubleshooting and Recovery
Undo last commit but keep changes:
```bash
git reset --soft HEAD~1
```
Recover deleted branch:
```bash
git reflog
git checkout -b <branch-name> <commit-id>
```
Fix detached HEAD:
```bash
git checkout main
```
---
## 16. Clone Repository
Clone via SSH:
```bash
git clone git@github.com:user/repo.git
```
Clone specific branch:
```bash
git clone -b <branch> <repo-url>
```

View File

@@ -1,20 +1,190 @@
diff :
# diff Command Reference
The `diff` command is a standard Unix/Linux utility used to compare files line by line. It is commonly used in development, DevOps, and system administration to identify changes between configuration files, source code, logs, or generated outputs.
---
## 1. Basic File Comparison
Compare two files line by line:
```bash
diff file1 file2
```
### Output Behavior
* Shows only the lines that differ
* Uses symbols to indicate changes:
* `<` line from `file1`
* `>` line from `file2`
* `c` change
* `a` addition
* `d` deletion
---
## 2. Side-by-Side Comparison
Display files next to each other:
```bash
diff -y file1 file2
```
### Notes
* Useful for human-readable comparison
* Differences are shown in two columns
* Change indicators appear in the middle
Limit output width:
```bash
diff -y --width=120 file1 file2
```
Suppress common lines:
```bash
diff -y --suppress-common-lines file1 file2
```
---
## 3. Unified Diff Format (Most Common)
Generate a unified diff:
```bash
diff -u file1 file2
```
### Why Unified Diff
* Standard format used by Git, patch, and code reviews
* Shows context before and after changes
* Easier to read and apply
Example output markers:
* `+` added lines
* `-` removed lines
* `@@` line numbers and context
---
## 4. Save Diff Output to a File
Redirect diff output to a file:
```bash
diff -u file1 file2 > diffrent
```
diff -u file1 file2 > different.diff
```
Common use cases:
* Code reviews
* Patch creation
* Change tracking
* CI/CD artifact storage
---
## 5. Recursive Directory Comparison
Compare directories:
```bash
diff -r dir1 dir2
```
Unified recursive diff:
```bash
diff -ru dir1 dir2
```
Ignore missing files:
```bash
diff -rq dir1 dir2
```
---
## 6. Ignore Differences
Ignore whitespace:
```bash
diff -w file1 file2
```
Ignore blank lines:
```bash
diff -B file1 file2
```
Ignore case differences:
```bash
diff -i file1 file2
```
---
## 7. Apply a Diff as a Patch
Create a patch:
```bash
diff -u oldfile newfile > change.patch
```
Apply patch:
```bash
patch < change.patch
```
Dry-run patch:
```bash
patch --dry-run < change.patch
```
---
## 8. diff vs Git diff
| diff | git diff |
| -------------------- | ------------------------------- |
| Compares any files | Compares Git-tracked files |
| Works without Git | Requires Git repository |
| Produces patch files | Integrated with version control |
---
## 9. Best Practices
* Use `-u` format for readability and compatibility
* Store diff files with `.diff` or `.patch` extensions
* Avoid committing generated diff files unless required
* Use `diff` for system configuration audits
* Use `git diff` inside Git repositories
---
## 10. Quick Reference
```bash
diff file1 file2
diff -y file1 file2
diff -u file1 file2
diff -ru dir1 dir2
diff -u file1 file2 > change.diff
```

View File

@@ -1,44 +1,243 @@
# Essential Date and Time Manipulation Commands
Here is a cleaned up, expanded, and more production-ready version of your **date and time manipulation** document, written from a DevOps / Linux system administration perspective and keeping it concise and accurate.
This document outlines common shell commands used for working with dates and times, essential for scripting, logging, and system administration tasks.
---
## 1. Creating Epoch Timestamps
# Essential Date and Time Manipulation Commands
The `date` command is versatile for generating timestamps in various formats, most notably the Unix epoch time (seconds since 1970-01-01 00:00:00 UTC).
This document covers common shell commands for working with dates and times. These commands are frequently used in scripting, logging, monitoring, automation, and system administration tasks.
### Command to Create Epoch Time (Milliseconds Precision)
---
This command converts a specific human-readable date and time into the epoch time, including milliseconds (`%3N`).
## 1. The `date` Command Overview
The `date` command is a standard Unix/Linux utility used to:
* Display the current system date and time
* Format timestamps
* Convert between human-readable dates and Unix epoch time
* Perform date arithmetic
Check system time:
```bash
date
```
---
## 2. Creating Epoch Timestamps
### Current Epoch Time (Seconds)
```bash
date +%s
```
Output example:
```
1737154200
```
### Current Epoch Time (Milliseconds)
```bash
date +%s%3N
```
Notes:
* `%s` → seconds since Unix epoch
* `%3N` → milliseconds (GNU date only)
---
### Convert Specific Date to Epoch (Milliseconds)
Convert a human-readable date to epoch time:
```bash
date -d "2026-01-13 14:31:26" +%s%3N
```
## 2. Formatting Current Date and Time
Common use cases:
Displaying the current date and time in a readable or specific format.
* Log correlation
* API timestamps
* CI/CD pipeline timing
* Monitoring and alerting
| Command | Description | Example Output (Varies) |
| :--- | :--- | :--- |
| `date` | Default display | Wed Jan 17 10:30:00 UTC 2026 |
| `date +'%Y-%m-%d %H:%M:%S'` | Standard ISO format | 2026-01-17 10:30:00 |
| `date +%s` | Current epoch time (seconds) | 1737154200 |
---
## 3. Converting Epoch to Human Readable
## 3. Formatting Current Date and Time
Converting a numeric epoch timestamp back into a readable format.
Custom output formats are widely used in scripts and logs.
### Common Date Formats
| Command | Description | Example Output |
| --------------------------- | --------------------- | ---------------------------- |
| `date` | Default system format | Wed Jan 17 10:30:00 UTC 2026 |
| `date +'%Y-%m-%d %H:%M:%S'` | ISO-like format | 2026-01-17 10:30:00 |
| `date +'%Y-%m-%d'` | Date only | 2026-01-17 |
| `date +'%H:%M:%S'` | Time only | 10:30:00 |
| `date +%s` | Epoch (seconds) | 1737154200 |
### Common Format Specifiers
| Specifier | Meaning |
| --------- | --------------- |
| `%Y` | Year (4 digits) |
| `%m` | Month (0112) |
| `%d` | Day (0131) |
| `%H` | Hour (0023) |
| `%M` | Minute (0059) |
| `%S` | Second (0060) |
| `%N` | Nanoseconds |
---
## 4. Converting Epoch to Human-Readable Time
Convert epoch seconds to readable format:
```bash
# Assuming $EPOCH_TIME holds a value like 1737154200
date -d @1737154200
```
Using a variable:
```bash
EPOCH_TIME=1737154200
date -d @"$EPOCH_TIME"
```
## 4. Date Arithmetic
Formatted output:
Calculating dates relative to the current time.
```bash
date -d @"$EPOCH_TIME" '+%Y-%m-%d %H:%M:%S'
```
| Command | Description | Example Output (Varies) |
| :--- | :--- | :--- |
| `date -d "yesterday"` | The previous day | Tue Jan 16 ... |
| `date -d "2 weeks ago"` | Two weeks prior | Thu Jan 03 ... |
| `date -d "+1 hour"` | One hour from now | Wed Jan 17 11:30:00 UTC 2026 |
---
## 5. Date Arithmetic
GNU `date` supports flexible date calculations.
### Relative Dates
| Command | Description |
| ----------------------- | ----------------------- |
| `date -d "yesterday"` | Previous day |
| `date -d "tomorrow"` | Next day |
| `date -d "2 days ago"` | Two days in the past |
| `date -d "+1 hour"` | One hour from now |
| `date -d "+30 minutes"` | Thirty minutes from now |
| `date -d "+1 week"` | One week from now |
| `date -d "2 weeks ago"` | Two weeks ago |
---
## 6. Date Arithmetic with Formatting
Example: date 7 days from now:
```bash
date -d "+7 days" '+%Y-%m-%d'
```
Example: timestamp 15 minutes ago (epoch):
```bash
date -d "-15 minutes" +%s
```
---
## 7. Working with UTC and Time Zones
Display current UTC time:
```bash
date -u
```
Format UTC time:
```bash
date -u '+%Y-%m-%d %H:%M:%S'
```
Convert date in a specific timezone:
```bash
TZ=UTC date
TZ=America/New_York date
```
---
## 8. Script-Friendly Usage Examples
Add timestamp to a log entry:
```bash
echo "$(date '+%Y-%m-%d %H:%M:%S') Application started"
```
Generate a timestamped filename:
```bash
backup_$(date +%Y%m%d_%H%M%S).tar.gz
```
Measure execution time:
```bash
start=$(date +%s)
# command here
end=$(date +%s)
echo "Duration: $((end - start)) seconds"
```
---
## 9. macOS Compatibility Notes
macOS uses BSD `date`, which differs from GNU `date`.
Example difference:
```bash
# GNU (Linux)
date -d "yesterday"
# BSD (macOS)
date -v -1d
```
Install GNU date on macOS:
```bash
brew install coreutils
gdate -d "yesterday"
```
---
## 10. Best Practices
* Use UTC for logs and distributed systems
* Store timestamps as epoch values when possible
* Format dates only at display time
* Avoid locale-dependent formats in scripts
* Be aware of GNU vs BSD `date` differences
---
If you want, I can:
* Add cron-specific date examples
* Add log rotation and backup use cases
* Provide a quick-reference cheat sheet
* Add cross-platform date handling strategies

View File

@@ -1,69 +1,239 @@
## OpenSSL Command Reference for Self-Signed Certificate Generation
# OpenSSL Command Reference for Self-Signed Certificate Generation
This document provides an overview of the `openssl` command-line tool and details the steps for generating a self-signed SSL/TLS certificate using specific commands.
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.
---
### What is OpenSSL?
## 1. What is OpenSSL?
**OpenSSL** is a powerful, open-source command-line toolkit implementing the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. It is widely used for generating private keys, creating Certificate Signing Requests (CSRs), managing certificates, and performing cryptographic operations.
**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
```
---
### Generating a Self-Signed Certificate (Example: For Gitea)
## 2. When to Use Self-Signed Certificates
The following sequence generates a private key, creates a CSR, and then uses the key and CSR to sign and create a self-signed certificate.
Self-signed certificates are suitable for:
#### Step 1: Generate a Private Key
* Internal services
* Development and staging environments
* Private networks
* Lab and proof-of-concept setups
This command creates an RSA private key of 2048 bits and saves it to a file named `gitea.key`.
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
```
| Component | Description |
| :--- | :--- |
| `genrsa` | Subcommand to generate an RSA private key. |
| `-out gitea.key` | Specifies the output file for the private key. |
| `2048` | Defines the key length in bits (2048 is a common standard). |
### Explanation
#### Step 2: Create a Certificate Signing Request (CSR)
| 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) |
This command uses the generated private key (`gitea.key`) to create a Certificate Signing Request (`gitea.csr`). The CSR contains your public key and identity information (like Common Name, Organization) that a Certificate Authority (CA) would normally use to issue a trusted certificate.
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
```
| Component | Description |
| :--- | :--- |
| `req` | Subcommand used for CSR management and certificate requests. |
| `-new` | Indicates that a new CSR is being created. |
| `-key gitea.key` | Specifies the private key to be associated with this request. |
| `-out gitea.csr` | Specifies the output file for the CSR. |
| *Interactive Prompt* | OpenSSL will prompt you to enter certificate details (Country Name, Common Name, etc.). **The Common Name (CN) should usually match the domain name** where the service (e.g., Gitea) will be hosted. |
### Explanation
#### Step 3: Create the Self-Signed Certificate
| 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 |
This command takes the CSR and the private key and signs the request with the key itself, creating a certificate (`gitea.crt`) that is valid immediately but *not* trusted by default by web browsers or clients (since it's not signed by a recognized CA).
### 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
```
| Component | Description |
| :--- | :--- |
| `x509` | Subcommand used for X.509 certificate management (like viewing, signing, testing). |
| `-req` | Specifies that the input file is a CSR. |
| `-in gitea.csr` | Specifies the input CSR file. |
| `-signkey gitea.key` | Uses the private key to sign the certificate request, making it self-signed. |
| `-out gitea.crt` | Specifies the output file for the final certificate. |
### 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
```
---
### Summary of Generated Files
## 7. Verify the Certificate
1. **`gitea.key`**: The **Private Key**. Must be kept secret and secure. Used by the server (e.g., Gitea) to decrypt incoming traffic.
2. **`gitea.csr`**: The **Certificate Signing Request**. Contains identifying information and the public key. (Not strictly needed after Step 3).
3. **`gitea.crt`**: The **Self-Signed Certificate**. Contains the public key and identity details, signed by your private key. This is what the server presents to clients.
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 Lets 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