Initial commit
This commit is contained in:
commit
62f2690fb5
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*.swo
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
252
README.md
Normal file
252
README.md
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
# myca-tools
|
||||||
|
|
||||||
|
Bash helpers for running a simple local root CA, issuing TLS certificates with SANs, and generating Nginx HTTPS reverse-proxy vhosts for internal services.
|
||||||
|
|
||||||
|
Do not use `.local`. Use `.lan` or a domain you control.
|
||||||
|
|
||||||
|
## Placeholders used in this README
|
||||||
|
|
||||||
|
- `NAME`
|
||||||
|
The service hostname you want to secure. Example: `app.lan`.
|
||||||
|
|
||||||
|
- `HOST_IP`
|
||||||
|
The local IP address of the server that presents the certificate. In a typical setup this is the machine running Nginx and hosting the service. Example: `192.168.1.50`.
|
||||||
|
|
||||||
|
- `BACKEND_HOST:PORT`
|
||||||
|
Where Nginx should proxy. Example: `127.0.0.1:8080`.
|
||||||
|
|
||||||
|
Replace these with your values before running commands.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Initialise a root CA in `/etc/ssl/myca`
|
||||||
|
- Issue server certificates with DNS and IP SANs
|
||||||
|
- Sign existing CSRs
|
||||||
|
- Show and verify certificates
|
||||||
|
- Deploy certs to `/etc/nginx/ssl` and reload Nginx
|
||||||
|
- Generate a standard HTTPS reverse proxy vhost
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Debian or Ubuntu
|
||||||
|
- `openssl`
|
||||||
|
- `nginx` if you want reverse proxying
|
||||||
|
- Root access
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <your-repo-url> myca-tools
|
||||||
|
cd myca-tools
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Installs:
|
||||||
|
|
||||||
|
/usr/local/sbin/myca.sh
|
||||||
|
|
||||||
|
/usr/local/sbin/mknginx-sni.sh
|
||||||
|
|
||||||
|
/usr/local/sbin/init-ca.sh
|
||||||
|
|
||||||
|
Prepares /etc/ssl/myca with certs, csrs, exts, and private.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
1. Initialise a root CA if you do not already have one.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo init-ca.sh "/CN=My Local Root CA"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Trust the CA on this host.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo myca.sh trust-ca
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Issue a cert for your internal service and deploy it to Nginx.
|
||||||
|
```bash
|
||||||
|
# Replace NAME and HOST_IP
|
||||||
|
sudo myca.sh issue NAME \
|
||||||
|
--dns NAME --ip HOST_IP --deploy-nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Create an Nginx vhost that uses the cert and proxies to your backend.
|
||||||
|
```bash
|
||||||
|
# Replace NAME and BACKEND_HOST:PORT
|
||||||
|
sudo mknginx-sni.sh NAME BACKEND_HOST:PORT
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Ensure clients resolve the name.
|
||||||
|
```bash
|
||||||
|
HOST_IP NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Test.
|
||||||
|
```bash
|
||||||
|
myca.sh show NAME
|
||||||
|
myca.sh verify NAME
|
||||||
|
curl -Ik https://NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes on SANs
|
||||||
|
|
||||||
|
You can omit --ip HOST_IP if clients always connect by DNS name and do not pin the IP.
|
||||||
|
|
||||||
|
If clients connect by IP, include that IP in SANs with --ip.
|
||||||
|
|
||||||
|
You can supply multiple --dns and --ip flags.
|
||||||
|
|
||||||
|
Scripts
|
||||||
|
myca.sh
|
||||||
|
|
||||||
|
Helper for issuing, signing, showing, verifying, and deploying certificates.
|
||||||
|
```bash
|
||||||
|
myca.sh COMMAND [args]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
issue NAME [--dns foo --ip 1.2.3.4 ...] [--days N] [--reuse-key] [--deploy-nginx]
|
||||||
|
sign NAME --csr /path/to/file.csr [--dns ... --ip ...] [--days N]
|
||||||
|
show NAME | /path/to/cert.crt
|
||||||
|
verify NAME | /path/to/cert.crt
|
||||||
|
list
|
||||||
|
trust-ca
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
MYCA_DIR default /etc/ssl/myca
|
||||||
|
NGINX_SSL_DIR default /etc/nginx/ssl
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```bash
|
||||||
|
# Issue new key and cert with SANs
|
||||||
|
sudo myca.sh issue internal-api.lan --dns internal-api.lan --ip HOST_IP
|
||||||
|
|
||||||
|
# Reissue keeping the same key and deploy to Nginx
|
||||||
|
sudo myca.sh issue wiki.lan --dns wiki.lan --reuse-key --deploy-nginx
|
||||||
|
|
||||||
|
# Sign an existing CSR
|
||||||
|
sudo myca.sh sign portal.lan --csr /tmp/portal.csr --dns portal.lan --ip 10.0.0.5
|
||||||
|
|
||||||
|
# Show and verify
|
||||||
|
myca.sh show wiki.lan
|
||||||
|
myca.sh verify wiki.lan
|
||||||
|
|
||||||
|
# List issued certs
|
||||||
|
myca.sh list
|
||||||
|
```
|
||||||
|
|
||||||
|
Files are written to:
|
||||||
|
|
||||||
|
Keys /etc/ssl/myca/private/NAME.key
|
||||||
|
|
||||||
|
CSRs /etc/ssl/myca/csrs/NAME.csr
|
||||||
|
|
||||||
|
Certs /etc/ssl/myca/certs/NAME.crt
|
||||||
|
|
||||||
|
SAN /etc/ssl/myca/exts/NAME.ext
|
||||||
|
|
||||||
|
CA files expected:
|
||||||
|
|
||||||
|
/etc/ssl/myca/myCA.pem
|
||||||
|
|
||||||
|
/etc/ssl/myca/myCA.key
|
||||||
|
|
||||||
|
/etc/ssl/myca/myCA.srl created on first issuance
|
||||||
|
|
||||||
|
mknginx-sni.sh
|
||||||
|
|
||||||
|
Generate a standard HTTPS reverse proxy server block for a given name and backend.
|
||||||
|
```bash
|
||||||
|
sudo mknginx-sni.sh NAME [BACKEND_HOST:PORT]
|
||||||
|
# writes /etc/nginx/conf.d/NAME.conf
|
||||||
|
# proxies to BACKEND, default 127.0.0.1:8000
|
||||||
|
# uses /etc/nginx/ssl/NAME.crt and /etc/nginx/ssl/NAME.key
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```bash
|
||||||
|
sudo mknginx-sni.sh internal-api.lan 127.0.0.1:9000
|
||||||
|
```
|
||||||
|
|
||||||
|
init-ca.sh
|
||||||
|
|
||||||
|
Initialise a new root CA in /etc/ssl/myca.
|
||||||
|
```bash
|
||||||
|
sudo init-ca.sh "/CN=My Local Root CA"
|
||||||
|
```
|
||||||
|
|
||||||
|
Creates:
|
||||||
|
|
||||||
|
Root key /etc/ssl/myca/myCA.key 4096 bit
|
||||||
|
|
||||||
|
Root cert /etc/ssl/myca/myCA.pem valid 10 years
|
||||||
|
|
||||||
|
Trusting your CA on clients
|
||||||
|
|
||||||
|
Linux Debian or Ubuntu:
|
||||||
|
```bash
|
||||||
|
sudo cp /etc/ssl/myca/myCA.pem /usr/local/share/ca-certificates/myCA.crt
|
||||||
|
sudo update-ca-certificates
|
||||||
|
```
|
||||||
|
|
||||||
|
ndows:
|
||||||
|
|
||||||
|
Import myCA.pem into Local Computer, Trusted Root Certification Authorities.
|
||||||
|
|
||||||
|
macOS:
|
||||||
|
|
||||||
|
Import myCA.pem into the System keychain in Keychain Access. Set Always Trust.
|
||||||
|
|
||||||
|
Browsers must trust the CA or you will see warnings.
|
||||||
|
|
||||||
|
Directory layout
|
||||||
|
```vbnet
|
||||||
|
/etc/ssl/myca/
|
||||||
|
├── myCA.key root key
|
||||||
|
├── myCA.pem root certificate
|
||||||
|
├── myCA.srl serial file
|
||||||
|
├── certs/ issued certificates
|
||||||
|
├── csrs/ certificate signing requests
|
||||||
|
├── exts/ SAN extension files
|
||||||
|
└── private/ server private keys
|
||||||
|
```
|
||||||
|
|
||||||
|
Nginx deploy target:
|
||||||
|
```swift
|
||||||
|
/etc/nginx/ssl/NAME.crt
|
||||||
|
/etc/nginx/ssl/NAME.key
|
||||||
|
```
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
Override defaults if needed:
|
||||||
|
```bash
|
||||||
|
export MYCA_DIR=/srv/pki
|
||||||
|
export NGINX_SSL_DIR=/etc/nginx/ssl
|
||||||
|
```
|
||||||
|
|
||||||
|
Security
|
||||||
|
|
||||||
|
Back up /etc/ssl/myca/myCA.key offline. Losing it prevents renewal under the same root.
|
||||||
|
|
||||||
|
Keep /etc/ssl/myca/private permissions intact. Keys are mode 600.
|
||||||
|
|
||||||
|
Keep this root CA for internal use only. Do not use it on the public internet.
|
||||||
|
|
||||||
|
Use shorter lifetimes for anything exposed beyond your LAN.
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
|
||||||
|
Missing CA: ensure myCA.pem and myCA.key exist under /etc/ssl/myca.
|
||||||
|
|
||||||
|
verify error:num=20: the client does not trust your CA. Install the CA to the client trust store.
|
||||||
|
|
||||||
|
Browser still warns after trusting CA: clear the site’s cached cert or restart the browser.
|
||||||
|
|
||||||
|
Nginx reload fails: run nginx -t and fix the reported error.
|
||||||
|
|
||||||
|
Licence
|
||||||
|
|
||||||
|
MIT.
|
||||||
25
bin/init-ca.sh
Normal file
25
bin/init-ca.sh
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Initialise a simple local root CA in /etc/ssl/myca
|
||||||
|
set -euo pipefail
|
||||||
|
MYCA_DIR="${MYCA_DIR:-/etc/ssl/myca}"
|
||||||
|
CN="${1:-/CN=Local Development Root CA}"
|
||||||
|
DAYS="${DAYS:-3650}"
|
||||||
|
|
||||||
|
install -d -m 755 "$MYCA_DIR" "$MYCA_DIR/certs" "$MYCA_DIR/csrs" "$MYCA_DIR/exts"
|
||||||
|
install -d -m 700 "$MYCA_DIR/private"
|
||||||
|
|
||||||
|
if [[ -e "$MYCA_DIR/myCA.key" || -e "$MYCA_DIR/myCA.pem" ]]; then
|
||||||
|
echo "CA already exists in $MYCA_DIR" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
openssl genrsa -out "$MYCA_DIR/myCA.key" 4096
|
||||||
|
chmod 600 "$MYCA_DIR/myCA.key"
|
||||||
|
|
||||||
|
openssl req -x509 -new -nodes -key "$MYCA_DIR/myCA.key" -sha256 -days "$DAYS" \
|
||||||
|
-out "$MYCA_DIR/myCA.pem" -subj "$CN"
|
||||||
|
|
||||||
|
chmod 644 "$MYCA_DIR/myCA.pem"
|
||||||
|
echo "Root CA created: $MYCA_DIR/myCA.pem"
|
||||||
|
echo "Private key: $MYCA_DIR/myCA.key"
|
||||||
|
|
||||||
44
bin/mknginx-sni.sh
Normal file
44
bin/mknginx-sni.sh
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Generate a standard SSL reverse proxy server block for NAME and backend HOST:PORT.
|
||||||
|
set -euo pipefail
|
||||||
|
name="${1:-}"; backend="${2:-127.0.0.1:8000}"
|
||||||
|
[[ -n "$name" ]] || { echo "Usage: mknginx-sni.sh NAME [BACKEND_HOST:PORT]"; exit 2; }
|
||||||
|
|
||||||
|
cat >/etc/nginx/conf.d/"$name".conf <<NGINX
|
||||||
|
upstream ${name//./_}_app { server $backend; keepalive 32; }
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name $name;
|
||||||
|
return 301 https://\$host\$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name $name;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/$name.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/$name.key;
|
||||||
|
|
||||||
|
client_max_body_size 100m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://${name//./_}_app;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection \$connection_upgrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map \$http_upgrade \$connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
|
||||||
|
nginx -t && systemctl reload nginx
|
||||||
|
echo "/etc/nginx/conf.d/$name.conf written"
|
||||||
|
|
||||||
221
bin/myca.sh
Normal file
221
bin/myca.sh
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Simple local CA helper for issuing server certs with SANs, verifying, and optional nginx deploy.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MYCA_DIR="${MYCA_DIR:-/etc/ssl/myca}"
|
||||||
|
CERT_DIR="$MYCA_DIR/certs"
|
||||||
|
KEY_DIR="$MYCA_DIR/private"
|
||||||
|
CSR_DIR="$MYCA_DIR/csrs"
|
||||||
|
EXT_DIR="$MYCA_DIR/exts"
|
||||||
|
NGINX_SSL_DIR="${NGINX_SSL_DIR:-/etc/nginx/ssl}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'USAGE'
|
||||||
|
myca.sh COMMAND [args]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
issue NAME [--dns foo --ip 1.2.3.4 ...] [--days N] [--reuse-key] [--deploy-nginx]
|
||||||
|
Create key + CSR + SAN ext, sign with CA, write cert.
|
||||||
|
sign NAME --csr /path/to/file.csr [--dns ... --ip ...] [--days N]
|
||||||
|
Sign an existing CSR with SANs.
|
||||||
|
show NAME|/path/to/cert.crt
|
||||||
|
Show subject, SANs, validity.
|
||||||
|
verify NAME|/path/to/cert.crt
|
||||||
|
Verify against CA.
|
||||||
|
list
|
||||||
|
List issued certs.
|
||||||
|
trust-ca
|
||||||
|
Install CA into Debian or Ubuntu trust store and update.
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
MYCA_DIR Default /etc/ssl/myca
|
||||||
|
NGINX_SSL_DIR Default /etc/nginx/ssl
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
myca.sh issue snipe-it.lan --dns snipe-it.lan --ip 192.168.17.51 --deploy-nginx
|
||||||
|
myca.sh show snipe-it.lan
|
||||||
|
myca.sh verify snipe-it.lan
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- CA files expected: $MYCA_DIR/myCA.pem and $MYCA_DIR/myCA.key
|
||||||
|
- Avoid .local hostnames. Use .lan or a domain you control.
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_dirs() {
|
||||||
|
install -d -m 755 "$CERT_DIR" "$CSR_DIR" "$EXT_DIR"
|
||||||
|
install -d -m 700 "$KEY_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
have_ca() {
|
||||||
|
[[ -s "$MYCA_DIR/myCA.pem" && -s "$MYCA_DIR/myCA.key" ]] || {
|
||||||
|
echo "Missing CA: $MYCA_DIR/myCA.pem or myCA.key" >&2; exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
make_ext() {
|
||||||
|
local name="$1"; shift
|
||||||
|
local dns_arr=() ip_arr=()
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--dns) dns_arr+=("$2"); shift 2;;
|
||||||
|
--ip) ip_arr+=("$2"); shift 2;;
|
||||||
|
*) echo "Unknown ext arg: $1" >&2; exit 2;;
|
||||||
|
case_esac
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local has_cn=0
|
||||||
|
for d in "${dns_arr[@]:-}"; do [[ "$d" == "$name" ]] && has_cn=1; done
|
||||||
|
[[ $has_cn -eq 0 ]] && dns_arr=("$name" "${dns_arr[@]:-}")
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "basicConstraints=CA:FALSE"
|
||||||
|
echo "keyUsage=digitalSignature,keyEncipherment"
|
||||||
|
echo "extendedKeyUsage=serverAuth"
|
||||||
|
echo "subjectAltName=@alt_names"
|
||||||
|
echo "[alt_names]"
|
||||||
|
local i=1
|
||||||
|
for d in "${dns_arr[@]:-}"; do echo "DNS.$i=$d"; i=$((i+1)); done
|
||||||
|
i=1
|
||||||
|
for ip in "${ip_arr[@]:-}"; do echo "IP.$i=$ip"; i=$((i+1)); done
|
||||||
|
} > "$EXT_DIR/$name.ext"
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_key_csr() {
|
||||||
|
local name="$1"
|
||||||
|
openssl genrsa -out "$KEY_DIR/$name.key" 2048 >/dev/null 2>&1
|
||||||
|
chmod 600 "$KEY_DIR/$name.key"
|
||||||
|
openssl req -new -key "$KEY_DIR/$name.key" \
|
||||||
|
-out "$CSR_DIR/$name.csr" -subj "/CN=$name" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
sign_csr() {
|
||||||
|
local name="$1" days="$2"
|
||||||
|
local serial_flag
|
||||||
|
if [[ -s "$MYCA_DIR/myCA.srl" ]]; then
|
||||||
|
serial_flag=(-CAserial "$MYCA_DIR/myCA.srl")
|
||||||
|
else
|
||||||
|
serial_flag=(-CAcreateserial)
|
||||||
|
fi
|
||||||
|
openssl x509 -req -in "$CSR_DIR/$name.csr" \
|
||||||
|
-CA "$MYCA_DIR/myCA.pem" -CAkey "$MYCA_DIR/myCA.key" \
|
||||||
|
"${serial_flag[@]}" -out "$CERT_DIR/$name.crt" -days "$days" -sha256 \
|
||||||
|
-extfile "$EXT_DIR/$name.ext" >/dev/null 2>&1
|
||||||
|
chmod 644 "$CERT_DIR/$name.crt"
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy_nginx() {
|
||||||
|
local name="$1"
|
||||||
|
install -d -m 755 "$NGINX_SSL_DIR"
|
||||||
|
install -m 644 "$CERT_DIR/$name.crt" "$NGINX_SSL_DIR/$name.crt"
|
||||||
|
install -m 600 "$KEY_DIR/$name.key" "$NGINX_SSL_DIR/$name.key"
|
||||||
|
if command -v nginx >/dev/null 2>&1; then
|
||||||
|
nginx -t && systemctl reload nginx || true
|
||||||
|
fi
|
||||||
|
echo "Deployed to $NGINX_SSL_DIR/$name.{crt,key}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_issue() {
|
||||||
|
local name days=825 reuse_key=0 deploy=0
|
||||||
|
local dns_args=() ip_args=()
|
||||||
|
shift
|
||||||
|
[[ $# -ge 1 ]] || { usage; exit 2; }
|
||||||
|
name="$1"; shift
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--days) days="$2"; shift 2;;
|
||||||
|
--reuse-key) reuse_key=1; shift;;
|
||||||
|
--deploy-nginx) deploy=1; shift;;
|
||||||
|
--dns) dns_args+=("$2"); shift 2;;
|
||||||
|
--ip) ip_args+=("$2"); shift 2;;
|
||||||
|
*) echo "Unknown option: $1" >&2; exit 2;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
ensure_dirs; have_ca
|
||||||
|
make_ext "$name" $(for d in "${dns_args[@]:-}"; do printf -- " --dns %q" "$d"; done) \
|
||||||
|
$(for i in "${ip_args[@]:-}"; do printf -- " --ip %q" "$i"; done)
|
||||||
|
|
||||||
|
if [[ $reuse_key -eq 0 || ! -s "$KEY_DIR/$name.key" ]]; then
|
||||||
|
gen_key_csr "$name"
|
||||||
|
else
|
||||||
|
openssl req -new -key "$KEY_DIR/$name.key" \
|
||||||
|
-out "$CSR_DIR/$name.csr" -subj "/CN=$name" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sign_csr "$name" "$days"
|
||||||
|
echo "Issued: $CERT_DIR/$name.crt"
|
||||||
|
[[ $deploy -eq 1 ]] && deploy_nginx "$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_sign_existing() {
|
||||||
|
local name csr_path="" days=825
|
||||||
|
local dns_args=() ip_args=()
|
||||||
|
shift
|
||||||
|
[[ $# -ge 1 ]] || { usage; exit 2; }
|
||||||
|
name="$1"; shift
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--csr) csr_path="$2"; shift 2;;
|
||||||
|
--days) days="$2"; shift 2;;
|
||||||
|
--dns) dns_args+=("$2"); shift 2;;
|
||||||
|
--ip) ip_args+=("$2"); shift 2;;
|
||||||
|
*) echo "Unknown option: $1" >&2; exit 2;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
[[ -n "$csr_path" && -s "$csr_path" ]] || { echo "CSR not found" >&2; exit 1; }
|
||||||
|
ensure_dirs; have_ca
|
||||||
|
cp -f "$csr_path" "$CSR_DIR/$name.csr"
|
||||||
|
make_ext "$name" $(for d in "${dns_args[@]:-}"; do printf -- " --dns %q" "$d"; done) \
|
||||||
|
$(for i in "${ip_args[@]:-}"; do printf -- " --ip %q" "$i"; done)
|
||||||
|
sign_csr "$name" "$days"
|
||||||
|
echo "Signed: $CERT_DIR/$name.crt"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_show() {
|
||||||
|
local target="${1:-}"
|
||||||
|
[[ -n "$target" ]] || { usage; exit 2; }
|
||||||
|
[[ "$target" == *.crt || "$target" == *.pem ]] || target="$CERT_DIR/$target.crt"
|
||||||
|
[[ -s "$target" ]] || { echo "Cert not found: $target" >&2; exit 1; }
|
||||||
|
openssl x509 -in "$target" -noout -subject -issuer -dates
|
||||||
|
echo "SANs:"
|
||||||
|
openssl x509 -in "$target" -noout -text | awk '/Subject Alternative Name/{f=1;next}/X509v3/{f=0}f'
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_verify() {
|
||||||
|
local target="${1:-}"
|
||||||
|
[[ -n "$target" ]] || { usage; exit 2; }
|
||||||
|
[[ "$target" == *.crt || "$target" == *.pem ]] || target="$CERT_DIR/$target.crt"
|
||||||
|
[[ -s "$target" ]] || { echo "Cert not found: $target" >&2; exit 1; }
|
||||||
|
have_ca
|
||||||
|
openssl verify -CAfile "$MYCA_DIR/myCA.pem" "$target"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_list() {
|
||||||
|
ensure_dirs
|
||||||
|
ls -1 "$CERT_DIR"/*.crt 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_trust_ca() {
|
||||||
|
have_ca
|
||||||
|
install -m 644 "$MYCA_DIR/myCA.pem" /usr/local/share/ca-certificates/myCA.crt
|
||||||
|
update-ca-certificates
|
||||||
|
echo "CA installed to system trust."
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
[[ $# -ge 1 ]] || { usage; exit 2; }
|
||||||
|
case "$1" in
|
||||||
|
issue) cmd_issue "$@";;
|
||||||
|
sign) cmd_sign_existing "$@";;
|
||||||
|
show) shift; cmd_show "${1:-}";;
|
||||||
|
verify) shift; cmd_verify "${1:-}";;
|
||||||
|
list) cmd_list;;
|
||||||
|
trust-ca) cmd_trust_ca;;
|
||||||
|
-h|--help|help) usage;;
|
||||||
|
*) echo "Unknown command: $1" >&2; usage; exit 2;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
main "$@"
|
||||||
|
|
||||||
33
examples/vhost-snipe-it.conf.example
Normal file
33
examples/vhost-snipe-it.conf.example
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
upstream snipe_it_lan_app { server 127.0.0.1:8000; keepalive 32; }
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name snipe-it.lan;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name snipe-it.lan;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/snipe-it.lan.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/snipe-it.lan.key;
|
||||||
|
|
||||||
|
client_max_body_size 100m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://snipe_it_lan_app;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
10
install.sh
Normal file
10
install.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
prefix="/usr/local/sbin"
|
||||||
|
sudo install -d -m 700 /etc/ssl/myca/private
|
||||||
|
sudo install -d -m 755 /etc/ssl/myca/{certs,csrs,exts}
|
||||||
|
sudo install -m 755 bin/myca.sh "$prefix/myca.sh"
|
||||||
|
sudo install -m 755 bin/mknginx-sni.sh "$prefix/mknginx-sni.sh"
|
||||||
|
sudo install -m 755 bin/init-ca.sh "$prefix/init-ca.sh"
|
||||||
|
echo "Installed to $prefix. CA dir at /etc/ssl/myca"
|
||||||
|
|
||||||
5
uninstall.sh
Normal file
5
uninstall.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
sudo rm -f /usr/local/sbin/{myca.sh,mknginx-sni.sh,init-ca.sh}
|
||||||
|
echo "Removed scripts. CA materials under /etc/ssl/myca left untouched."
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user