feat: 🚀 Switch to elliptical curves and rename cert/key files
parent
324ffeada3
commit
beea0a81d6
56
INSTALL.md
56
INSTALL.md
|
@ -330,8 +330,8 @@ A good place to keep your SSL certs and keys is in `/etc/ssl/private/mynet`. Let
|
||||||
```bash
|
```bash
|
||||||
tld='mynet'
|
tld='mynet'
|
||||||
crt_dir="/etc/ssl/private/${tld}"
|
crt_dir="/etc/ssl/private/${tld}"
|
||||||
ca_key="${crt_dir}/_ca.key"
|
ca_key="${crt_dir}/_ca/key.pem"
|
||||||
ca_crt="${crt_dir}/_ca.crt"
|
ca_crt="${crt_dir}/_ca/cert.pem"
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we'll create the ca key and cert. You will be asked for some details about your organization; put whatever you want. You'll also be asked to create a passphrase: create and store one using the most secure methods! You'll need this passphrase for the `wagon` config later.
|
Now we'll create the ca key and cert. You will be asked for some details about your organization; put whatever you want. You'll also be asked to create a passphrase: create and store one using the most secure methods! You'll need this passphrase for the `wagon` config later.
|
||||||
|
@ -344,7 +344,7 @@ openssl req -x509 -new -nodes -key "${ca_key}" -sha256 -days 3650 -out "${ca_crt
|
||||||
ln -s "${ca_crt}" "/etc/ssl/certs/${tld}.pem"
|
ln -s "${ca_crt}" "/etc/ssl/certs/${tld}.pem"
|
||||||
```
|
```
|
||||||
|
|
||||||
The last step makes the cert available to verification from the host OS. This cert file, `/etc/ssl/private/mynet/_ca.crt` should be shared with everyone who will be accessing your network. One easy way to do this is to serve it on your public website at `https://www.example.com/ca.crt` so users can easily download it. It must be added to every user's OS and/or browser. How this is done will depend on the OS and browser... so you should provide instructions to your users! A sample of such instructions can be found at [www.gf4.pw/nebuchadnezzar/ca/](https://www.gf4.pw/nebuchadnezzar/ca/).
|
The last step makes the cert available to verification from the host OS. This cert file, `/etc/ssl/private/mynet/_ca/cert.pem` should be shared with everyone who will be accessing your network. One easy way to do this is to serve it on your public website at `https://www.example.com/ca.crt` so users can easily download it. It must be added to every user's OS and/or browser. How this is done will depend on the OS and browser... so you should provide instructions to your users! A sample of such instructions can be found at [www.gf4.pw/nebuchadnezzar/ca/](https://www.gf4.pw/nebuchadnezzar/ca/).
|
||||||
|
|
||||||
We can use these CA files to sign certificates for hosts using our `mynet` domain. Let's sign one for the server first:
|
We can use these CA files to sign certificates for hosts using our `mynet` domain. Let's sign one for the server first:
|
||||||
|
|
||||||
|
@ -355,15 +355,15 @@ host=hn
|
||||||
domain="${host}.${tld}"
|
domain="${host}.${tld}"
|
||||||
crt_dir="/etc/ssl/private/${tld}"
|
crt_dir="/etc/ssl/private/${tld}"
|
||||||
host_dir="${crt_dir}/${host}"
|
host_dir="${crt_dir}/${host}"
|
||||||
ca_crt="${crt_dir}/_ca.crt"
|
ca_crt="${crt_dir}/_ca/cert.pem"
|
||||||
ca_key="${crt_dir}/_ca.key"
|
ca_key="${crt_dir}/_ca/key.pem"
|
||||||
ips='IP:10.99.0.1'
|
ips='IP:10.99.0.1'
|
||||||
|
|
||||||
# Create a subdirectory for the host's files
|
# Create a subdirectory for the host's files
|
||||||
mkdir -p "${host_dir}"
|
mkdir -p "${host_dir}"
|
||||||
|
|
||||||
# Generate the host's key
|
# Generate the host's key
|
||||||
openssl genrsa -out "${host_dir}/server.key" 2048
|
openssl genrsa -out "${host_dir}/key.pem" 2048
|
||||||
|
|
||||||
# Set certificate configuration
|
# Set certificate configuration
|
||||||
# If /etc/ssl/openssl.cnf doesn't exist, look for
|
# If /etc/ssl/openssl.cnf doesn't exist, look for
|
||||||
|
@ -374,7 +374,7 @@ cat /etc/ssl/openssl.cnf \
|
||||||
|
|
||||||
# Now we'll create the certificate signing request
|
# Now we'll create the certificate signing request
|
||||||
openssl req -new -sha256 -reqexts SAN \
|
openssl req -new -sha256 -reqexts SAN \
|
||||||
-key "${host_dir}/server.key" \
|
-key "${host_dir}/key.pem" \
|
||||||
-config "${crt_dir}/${host}.cnf" \
|
-config "${crt_dir}/${host}.cnf" \
|
||||||
-subj "/O=${org}/OU=${host}/CN=${domain}" \
|
-subj "/O=${org}/OU=${host}/CN=${domain}" \
|
||||||
-out "${crt_dir}/${host}.csr"
|
-out "${crt_dir}/${host}.csr"
|
||||||
|
@ -387,13 +387,13 @@ openssl x509 -req -sha256 -extensions SAN \
|
||||||
-CA "${ca_crt}" -CAkey "${ca_key}" \
|
-CA "${ca_crt}" -CAkey "${ca_key}" \
|
||||||
-in "${crt_dir}/${host}.csr" \
|
-in "${crt_dir}/${host}.csr" \
|
||||||
-extfile "${crt_dir}/${host}.cnf" \
|
-extfile "${crt_dir}/${host}.cnf" \
|
||||||
-out "${host_dir}/server.crt"
|
-out "${host_dir}/cert.pem"
|
||||||
```
|
```
|
||||||
|
|
||||||
That should do it! Let's check that the cert is valid for all domains and IPs:
|
That should do it! Let's check that the cert is valid for all domains and IPs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
openssl x509 -text -noout -in "${host_dir}/server.crt" | grep -A1 'Subject Alternative Name'
|
openssl x509 -text -noout -in "${host_dir}/cert.pem" | grep -A1 'Subject Alternative Name'
|
||||||
```
|
```
|
||||||
|
|
||||||
That should return something like:
|
That should return something like:
|
||||||
|
@ -416,38 +416,38 @@ org='My Cool Organization'
|
||||||
tld=mynet
|
tld=mynet
|
||||||
host='pc.myuser'
|
host='pc.myuser'
|
||||||
domain="${host}.${tld}"
|
domain="${host}.${tld}"
|
||||||
crt_dir="/etc/ssl/private/${tld}"
|
cert_dir="/etc/ssl/private/${tld}"
|
||||||
host_dir="${crt_dir}/${host}"
|
host_dir="${cert_dir}/${host}"
|
||||||
ca_crt="${crt_dir}/_ca.crt"
|
ca_crt="${cert_dir}/_ca/cert.pem"
|
||||||
ca_key="${crt_dir}/_ca.key"
|
ca_key="${cert_dir}/_ca/key.pem"
|
||||||
ips='IP:10.99.1.1'
|
ips='IP:10.99.1.1'
|
||||||
days=3650
|
days=3650
|
||||||
|
|
||||||
mkdir -p "${host_dir}"
|
mkdir -p "${host_dir}"
|
||||||
|
|
||||||
openssl genrsa -out "${host_dir}/server.key" 2048
|
openssl genrsa -out "${host_dir}/key.pem" 2048
|
||||||
|
|
||||||
cat /etc/ssl/openssl.cnf \
|
cat /etc/ssl/openssl.cnf \
|
||||||
<(printf "\n[SAN]\nsubjectAltName=DNS:${domain},DNS:*.${domain},${ips}\n") \
|
<(printf "\n[SAN]\nsubjectAltName=DNS:${domain},DNS:*.${domain},${ips}\n") \
|
||||||
>"${host_dir}.cnf"
|
>"${host_dir}.cnf"
|
||||||
|
|
||||||
openssl req -new -sha256 -reqexts SAN \
|
openssl req -new -sha256 -reqexts SAN \
|
||||||
-key "${host_dir}/server.key" \
|
-key "${host_dir}/key.pem" \
|
||||||
-config "${crt_dir}/${host}.cnf" \
|
-config "${cert_dir}/${host}.cnf" \
|
||||||
-subj "/O=${org}/OU=${host}/CN=${domain}" \
|
-subj "/O=${org}/OU=${host}/CN=${domain}" \
|
||||||
-out "${crt_dir}/${host}.csr"
|
-out "${cert_dir}/${host}.csr"
|
||||||
|
|
||||||
|
|
||||||
openssl x509 -req -sha256 -extensions SAN \
|
openssl x509 -req -sha256 -extensions SAN \
|
||||||
-CAcreateserial -days "3650"
|
-CAcreateserial -days "3650"
|
||||||
-CA "${ca_crt}" -CAkey "${ca_key}" \
|
-CA "${ca_crt}" -CAkey "${ca_key}" \
|
||||||
-in "${crt_dir}/${host}.csr" \
|
-in "${cert_dir}/${host}.csr" \
|
||||||
-extfile "${crt_dir}/${host}.cnf" \
|
-extfile "${cert_dir}/${host}.cnf" \
|
||||||
-out "${host_dir}/server.crt"
|
-out "${host_dir}/cert.pem"
|
||||||
|
|
||||||
openssl x509 -text -noout -in "${host_dir}/server.crt" | grep -A1 'Subject Alternative Name'
|
openssl x509 -text -noout -in "${host_dir}/cert.pem" | grep -A1 'Subject Alternative Name'
|
||||||
|
|
||||||
rm -f "${crt_dir}/${host}.csr" "${crt_dir}/${host}.cnf"
|
rm -f "${cert_dir}/${host}.csr" "${cert_dir}/${host}.cnf"
|
||||||
```
|
```
|
||||||
|
|
||||||
You might be thinking, this would all be easier as a script. A script that could add clients to wireguard and bind, then generate and server the ssl files. This is what `wagon` is designed to do.
|
You might be thinking, this would all be easier as a script. A script that could add clients to wireguard and bind, then generate and server the ssl files. This is what `wagon` is designed to do.
|
||||||
|
@ -492,8 +492,8 @@ IPV6_NET='fd69:1337:0:420:f4:99::/96'
|
||||||
IPV4_HUB=10.3.0.1
|
IPV4_HUB=10.3.0.1
|
||||||
IPV6_HUB=fd69:1337:0:420:f4:f3:0:1
|
IPV6_HUB=fd69:1337:0:420:f4:f3:0:1
|
||||||
SSL_CONFIG_DIR="/etc/ssl/private/${TLD}"
|
SSL_CONFIG_DIR="/etc/ssl/private/${TLD}"
|
||||||
SSL_CA_CERT="${SSL_CONFIG_DIR}/_ca.crt"
|
SSL_CA_CERT="${SSL_CONFIG_DIR}/_ca/cert.pem"
|
||||||
SSL_CA_KEY="${SSL_CONFIG_DIR}/_ca.key"
|
SSL_CA_KEY="${SSL_CONFIG_DIR}/_ca/key.pem"
|
||||||
SSL_ORG='My Cool Organization'
|
SSL_ORG='My Cool Organization'
|
||||||
SSL_DAYS='3650'
|
SSL_DAYS='3650'
|
||||||
SSL_CA_PASS='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
SSL_CA_PASS='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
||||||
|
@ -534,8 +534,8 @@ That's not bad. We could take requests on that port, but let's take secure https
|
||||||
server {
|
server {
|
||||||
server_name wagon-dashboard-api.hn.mynet;
|
server_name wagon-dashboard-api.hn.mynet;
|
||||||
listen 10.99.0.1:443 ssl http2;
|
listen 10.99.0.1:443 ssl http2;
|
||||||
ssl_certificate /etc/ssl/private/mynet/hn/server.crt;
|
ssl_certificate /etc/ssl/private/mynet/hn/cert.pem;
|
||||||
ssl_certificate_key /etc/ssl/private/mynet/hn/server.key;
|
ssl_certificate_key /etc/ssl/private/mynet/hn/key.pem;
|
||||||
ssl_stapling off;
|
ssl_stapling off;
|
||||||
allow 10.99.0.0/16; # All users
|
allow 10.99.0.0/16; # All users
|
||||||
deny all; # Everyone else
|
deny all; # Everyone else
|
||||||
|
@ -548,8 +548,8 @@ server {
|
||||||
server {
|
server {
|
||||||
server_name wagon-admin-api.hn.mynet;
|
server_name wagon-admin-api.hn.mynet;
|
||||||
listen 10.99.0.1:443 ssl http2;
|
listen 10.99.0.1:443 ssl http2;
|
||||||
ssl_certificate /etc/ssl/private/mynet/hn/server.crt;
|
ssl_certificate /etc/ssl/private/mynet/hn/cert.pem;
|
||||||
ssl_certificate_key /etc/ssl/private/mynet/hn/server.key;
|
ssl_certificate_key /etc/ssl/private/mynet/hn/key.pem;
|
||||||
ssl_stapling off;
|
ssl_stapling off;
|
||||||
allow 10.99.1.0/24; # One admin
|
allow 10.99.1.0/24; # One admin
|
||||||
allow 10.99.7.0/24; # Another admin
|
allow 10.99.7.0/24; # Another admin
|
||||||
|
|
|
@ -68,8 +68,8 @@ server {
|
||||||
server_name dev.mypc.myuser.mynet;
|
server_name dev.mypc.myuser.mynet;
|
||||||
listen 10.11.1.1:443 ssl http2;
|
listen 10.11.1.1:443 ssl http2;
|
||||||
|
|
||||||
ssl_certificate /path/to/downloaded/mypc.myuser.mynet/server.crt;
|
ssl_certificate /path/to/downloaded/mypc.myuser.mynet/cert.pem;
|
||||||
ssl_certificate_key /path/to/downloaded/mypc.myuser.mynet/server.key;
|
ssl_certificate_key /path/to/downloaded/mypc.myuser.mynet/key.pem;
|
||||||
ssl_stapling off;
|
ssl_stapling off;
|
||||||
|
|
||||||
allow 10.11.1.0/24; # My devices
|
allow 10.11.1.0/24; # My devices
|
||||||
|
@ -85,7 +85,7 @@ server {
|
||||||
|
|
||||||
## Dashboard
|
## Dashboard
|
||||||
|
|
||||||
Users can access a dashboard with a list of devices and links to download `server.crt` and `server.key`. Users can add and delete these devices, and admins can add/delete devices and users from a seperate admin interface. When adding a new user or device, the dashboard displays a wireguard configuration which must be copied or saved before the page is refreshed.
|
Users can access a dashboard with a list of devices and links to download `cert.pem` and `key.pem`. Users can add and delete these devices, and admins can add/delete devices and users from a seperate admin interface. When adding a new user or device, the dashboard displays a wireguard configuration which must be copied or saved before the page is refreshed.
|
||||||
|
|
||||||
In this way, there is no central server storing all the private keys, like with most wireguard dashboards. In fact, `wagon` does not have a database and does not store any data at all; everything is stored in the server's nameserver and wireguard config.
|
In this way, there is no central server storing all the private keys, like with most wireguard dashboards. In fact, `wagon` does not have a database and does not store any data at all; everything is stored in the server's nameserver and wireguard config.
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,17 @@ if ! sudo mkdir "${SSL_CONFIG_DIR:?}/${username:?}/${hostname:?}/"; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate key
|
# Generate key
|
||||||
if ! sudo /usr/bin/openssl genrsa -out "${SSL_CONFIG_DIR:?}/${username:?}/${hostname:?}/server.key" >>/dev/null 2>&1; then
|
if ! sudo /usr/bin/openssl ecparam -name secp384r1 -out "${SSL_CONFIG_DIR:?}/${username:?}/${hostname:?}/key.pem" >>/dev/null 2>&1; then
|
||||||
printf 'Failed to generate SSL key %s/%s/%s/server.key\n' "${SSL_CONFIG_DIR}" "${username}" "${hostname}" >&2
|
printf 'Failed to generate SSL key %s/%s/%s/key.pem\n' "${SSL_CONFIG_DIR}" "${username}" "${hostname}" >&2
|
||||||
exit 7
|
exit 7
|
||||||
fi
|
fi
|
||||||
if ! sudo [ -f "${SSL_CONFIG_DIR}/${username}/${hostname}/server.key" ]; then
|
if ! sudo [ -f "${SSL_CONFIG_DIR}/${username}/${hostname}/key.pem" ]; then
|
||||||
printf 'SSL key %s/%s/%s/server.key was not generated!\n' "${SSL_CONFIG_DIR}" "${username}" "${hostname}" >&2
|
printf 'SSL key %s/%s/%s/key.pem was not generated!\n' "${SSL_CONFIG_DIR}" "${username}" "${hostname}" >&2
|
||||||
ls "${SSL_CONFIG_DIR}/${username}/${hostname}/" >&2
|
ls "${SSL_CONFIG_DIR}/${username}/${hostname}/" >&2
|
||||||
exit 7
|
exit 7
|
||||||
fi
|
fi
|
||||||
if ! sudo chmod 400 "${SSL_CONFIG_DIR}/${username}/${hostname}/server.key" >&2 2>&1; then
|
if ! sudo chmod 400 "${SSL_CONFIG_DIR}/${username}/${hostname}/key.pem" >&2 2>&1; then
|
||||||
printf 'Failed to chmod SSL key %s/%s/%s/server.key\n' "${SSL_CONFIG_DIR}" "${username}" "${hostname}" >&2
|
printf 'Failed to chmod SSL key %s/%s/%s/key.pem\n' "${SSL_CONFIG_DIR}" "${username}" "${hostname}" >&2
|
||||||
exit 7
|
exit 7
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ if ! printf '%s\n' "${san}" | sudo cat '/etc/ssl/openssl.cnf' /dev/stdin \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate CSR
|
# Generate CSR
|
||||||
if ! sudo /usr/bin/openssl req -new -sha256 -reqexts SAN -extensions SAN \
|
if ! sudo /usr/bin/openssl req -new -sha384 -reqexts SAN -extensions SAN \
|
||||||
-key "${SSL_CONFIG_DIR}/${username}/${hostname}/server.key" \
|
-key "${SSL_CONFIG_DIR}/${username}/${hostname}/key.pem" \
|
||||||
-out "${SSL_CONFIG_DIR}/${username}/${hostname}.csr" \
|
-out "${SSL_CONFIG_DIR}/${username}/${hostname}.csr" \
|
||||||
-config "${SSL_CONFIG_DIR}/${username}/${hostname}.cnf" \
|
-config "${SSL_CONFIG_DIR}/${username}/${hostname}.cnf" \
|
||||||
-subj "/O=${SSL_ORG}/OU=${username}/CN=${hostname}.${username}.${TLD}" \
|
-subj "/O=${SSL_ORG}/OU=${username}/CN=${hostname}.${username}.${TLD}" \
|
||||||
|
@ -54,20 +54,20 @@ if ! sudo /usr/bin/openssl req -new -sha256 -reqexts SAN -extensions SAN \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate cert
|
# Generate cert
|
||||||
if ! sudo /usr/bin/openssl x509 -req -sha256 -extensions SAN -CAcreateserial \
|
if ! sudo /usr/bin/openssl x509 -req -sha384 -extensions SAN -CAcreateserial \
|
||||||
-extfile "${SSL_CONFIG_DIR}/${username}/${hostname}.cnf" \
|
-extfile "${SSL_CONFIG_DIR}/${username}/${hostname}.cnf" \
|
||||||
-in "${SSL_CONFIG_DIR}/${username}/${hostname}.csr" \
|
-in "${SSL_CONFIG_DIR}/${username}/${hostname}.csr" \
|
||||||
-CA "${SSL_CA_CERT}" -CAkey "${SSL_CA_KEY}" \
|
-CA "${SSL_CA_CERT}" -CAkey "${SSL_CA_KEY}" \
|
||||||
-passin "pass:${SSL_CA_PASS}" \
|
-passin "pass:${SSL_CA_PASS}" \
|
||||||
-out "${SSL_CONFIG_DIR}/${username}/${hostname}/server.crt" \
|
-out "${SSL_CONFIG_DIR}/${username}/${hostname}/cert.pem" \
|
||||||
-days "${SSL_DAYS}" >/dev/null 2>&1; then
|
-days "${SSL_DAYS}" >/dev/null 2>&1; then
|
||||||
printf 'ERROR! Failed to generate SSL cert %s/%s/server.crt\n' "${username}" "${hostname}" >&2
|
printf 'ERROR! Failed to generate SSL cert %s/%s/cert.pem\n' "${username}" "${hostname}" >&2
|
||||||
exit 7
|
exit 7
|
||||||
fi; if ! sudo [ -f "${SSL_CONFIG_DIR:?}/${username:?}/${hostname:?}/server.crt" ]; then
|
fi; if ! sudo [ -f "${SSL_CONFIG_DIR:?}/${username:?}/${hostname:?}/cert.pem" ]; then
|
||||||
printf 'ERROR! SSL key %s/%s/server.crt was not generated!\n' "${username}" "${hostname}" >&2
|
printf 'ERROR! SSL key %s/%s/cert.pem was not generated!\n' "${username}" "${hostname}" >&2
|
||||||
exit 7
|
exit 7
|
||||||
fi; if ! sudo chmod 640 "${SSL_CONFIG_DIR}/${username}/${hostname}/server.crt" "${SSL_CONFIG_DIR}/${username}/${hostname}/server.key"; then
|
fi; if ! sudo chmod 640 "${SSL_CONFIG_DIR}/${username}/${hostname}/cert.pem" "${SSL_CONFIG_DIR}/${username}/${hostname}/key.pem"; then
|
||||||
printf 'ERROR! Failed to chmod SSL cert %s/%s/server.*\n' "${username}" "${hostname}" >&2
|
printf 'ERROR! Failed to chmod SSL cert %s/%s/*.pem\n' "${username}" "${hostname}" >&2
|
||||||
exit 8
|
exit 8
|
||||||
fi & if ! sudo chgrp -R www-data "${SSL_CONFIG_DIR}/${username}/"; then
|
fi & if ! sudo chgrp -R www-data "${SSL_CONFIG_DIR}/${username}/"; then
|
||||||
printf 'ERROR! Failed to set group of %s!\n' "${SSL_CONFIG_DIR}/${username}/" >&2
|
printf 'ERROR! Failed to set group of %s!\n' "${SSL_CONFIG_DIR}/${username}/" >&2
|
||||||
|
|
|
@ -5,8 +5,8 @@ IPV6_NET='fd69:1337:0:420:f4:f3::/96'
|
||||||
IPV4_HUB=10.3.0.1
|
IPV4_HUB=10.3.0.1
|
||||||
IPV6_HUB=fd69:1337:0:420:f4:f3:0:1
|
IPV6_HUB=fd69:1337:0:420:f4:f3:0:1
|
||||||
SSL_CONFIG_DIR="/etc/ssl/private/${TLD}"
|
SSL_CONFIG_DIR="/etc/ssl/private/${TLD}"
|
||||||
SSL_CA_CERT="${SSL_CONFIG_DIR}/_ca.crt"
|
SSL_CA_CERT="${SSL_CONFIG_DIR}/_ca/cert.pem"
|
||||||
SSL_CA_KEY="${SSL_CONFIG_DIR}/_ca.key"
|
SSL_CA_KEY="${SSL_CONFIG_DIR}/_ca/key.pem"
|
||||||
SSL_ORG='My Org'
|
SSL_ORG='My Org'
|
||||||
SSL_DAYS='3650'
|
SSL_DAYS='3650'
|
||||||
SSL_CA_PASS='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
SSL_CA_PASS='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
||||||
|
|
Loading…
Reference in New Issue