Compare commits

...

17 Commits

Author SHA1 Message Date
John Lancaster
2bbf9b3f53 README tweaks 2026-01-03 09:20:46 -06:00
John Lancaster
86339f5115 default path updates 2026-01-03 00:50:17 -06:00
John Lancaster
5b55b02a76 readme updates 2026-01-03 00:46:48 -06:00
John Lancaster
d7cb02f506 fixes 2026-01-03 00:34:04 -06:00
John Lancaster
3ca2a092fd another rbac 2026-01-02 23:11:47 -06:00
John Lancaster
5e52facc5c tweak 2026-01-02 23:08:38 -06:00
John Lancaster
7914368111 more rbac 2026-01-02 23:08:29 -06:00
John Lancaster
586c4b47bc comments 2026-01-02 15:08:12 -06:00
John Lancaster
cb530aa864 comments 2026-01-02 14:49:10 -06:00
John Lancaster
a5d0b1cb2f comment 2026-01-02 14:37:26 -06:00
John Lancaster
b7537179c9 comments 2026-01-02 14:32:35 -06:00
John Lancaster
be29375bee comments 2026-01-02 14:24:51 -06:00
John Lancaster
454a6fe00c comments 2026-01-02 14:18:20 -06:00
John Lancaster
405e1fc05c ignore log files 2026-01-02 14:12:37 -06:00
John Lancaster
34898d9b11 access log for envoy 2026-01-02 14:12:30 -06:00
John Lancaster
be34df6324 envoy config tweaks 2026-01-02 14:12:22 -06:00
John Lancaster
f92924b74f added role-based access control (RBAC) 2026-01-02 13:32:42 -06:00
5 changed files with 129 additions and 43 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
certs/
*.log

View File

@@ -16,7 +16,8 @@ Connect solely through wireguard to `192.168.1.142` and serve the REST server wi
## Restic Repos
`/etc/fstab` entry:
`/etc/fstab` entry on Proxmox host:
```
john-nas:/volume1/restic /mnt/nfs/restic nfs nofail,_netdev,x-systemd.automount,x-systemd.idle-timeout=600,timeo=14,retrans=3,hard,tcp,nfsvers=3 0 0
```
@@ -36,27 +37,41 @@ pct set 103 -mp0 /mnt/nfs/restic,mp=/mnt/restic
Generate a new private key and (public) certificate in the right places. This will use the `admin` provisioner.
```
step ca certificate soteria.john-stream.com certs/soteria.crt certs/soteria.key --provisioner admin
export HOSTNAME=$(hostname -s) && \
export DOMAIN="john-stream.com" && \
export CERT_DIR="/var/lib/tls" && \
export IP_ADDRESS=$(ip -4 addr show dev eth0 | awk '/inet /{print $2}' | cut -d/ -f1)
```
```
(umask 077; mkdir -p "$CERT_DIR") && cd "$CERT_DIR" && \
step ca root root_ca.crt && \
step ca certificate "$HOSTNAME" cert.pem key.pem \
--san "$HOSTNAME" \
--san "$HOSTNAME.$DOMAIN" \
--san "$IP_ADDRESS" \
--san spiffe://john-stream.com/role/docker-agent \
--provisioner admin
```
Convert the key for Envoy to use:
```
(umask 027; openssl pkcs8 -topk8 -nocrypt -in key.pem -out key_pkcs8.pem)
```
Check the resultant certificate:
```
openssl x509 -noout -subject -issuer -ext extendedKeyUsage -ext subjectAltName -in certs/soteria.crt
openssl x509 -noout -subject -issuer -ext extendedKeyUsage,subjectAltName -in /var/lib/tls/cert.pem
```
Set up renewal
## Envoy Proxy
```bash
sudo ./scripts/install_services.sh
```
Test renewal
```
systemctl start cert-renewer.service && \
systemctl status cert-renewer.service --no-pager && \
Validate config:
```shell
docker compose run -it --rm envoy --mode validate -c /etc/envoy/envoy.yaml
```
## Clients
@@ -71,30 +86,37 @@ curl -sL https://gitea.john-stream.com/john/soteria/raw/branch/main/scripts/setu
curl -sL https://gitea.john-stream.com/john/soteria/raw/branch/main/scripts/check_status.sh | bash
```
```bash
curl -sL https://gitea.john-stream.com/john/soteria/raw/branch/main/scripts/wizard_setup.sh | bash
```
### Manual Setup
Set up provisioner password by running this and pasting in the current JWK provisioner password for `admin`
```
read -s secret && (umask 077; echo "$secret" > $(step path)/certs/secret.txt)
```
Generate the client TLS private key and (public) certificate for mTLS. This will combine them both into a file called `restic.pem`, which can be used with the `--tls-client-cert` option with the restic CLI.
```
cd $(step path)/certs && \
step ca certificate \
--provisioner admin --password-file secret.txt \
$(hostnamectl hostname) restic.crt restic.key && \
(umask 077; cat restic.crt restic.key > restic.pem)
export HOSTNAME=$(hostname -s) && \
export DOMAIN="john-stream.com" && \
export CERT_DIR="/var/lib/tls" && \
export IP_ADDRESS=$(ip -4 addr show dev eth0 | awk '/inet /{print $2}' | cut -d/ -f1) && \
(umask 077; mkdir -p "$CERT_DIR" && cd "$CERT_DIR" && \
step ca root root_ca.crt && \
step ca certificate "$HOSTNAME" cert.pem key.pem \
--san "$HOSTNAME" \
--san "$HOSTNAME.$DOMAIN" \
--san "$IP_ADDRESS" \
--san spiffe://john-stream.com/role/docker-agent \
--provisioner admin && \
cat {cert,key}.pem > restic.pem) && \
chmod 644 cert.pem root_ca.crt
```
Need restic 0.16+ for the env vars `RESTIC_CACERT` and `RESTIC_TLS_CLIENT_CERT` to work.
```
export RESTIC_CACERT=$(step path)/certs/root_ca.crt
export RESTIC_TLS_CLIENT_CERT=$(step path)/certs/restic.pem
export RESTIC_REPOSITORY=rest:https://soteria.john-stream.com/john-ubuntu
export RESTIC_CACERT=$(step path)/certs/root_ca.crt && \
export RESTIC_TLS_CLIENT_CERT=$(step path)/certs/restic.pem && \
export RESTIC_REPOSITORY=rest:https://soteria.john-stream.com/john-ubuntu && \
export RESTIC_PASSWORD_FILE=$(readlink -f ~/.config/resticprofile/password.txt)
```
@@ -106,6 +128,8 @@ restic snapshots
### Installing Latest Binary
Do this in case the restic version from apt is too old.
```
curl -s https://api.github.com/repos/restic/restic/releases/latest | grep tag_name
```

View File

@@ -18,5 +18,6 @@ services:
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml:ro
- /var/lib/tls:/certs
- ./access.log:/var/log/envoy/access.log
depends_on:
- rest-server

View File

@@ -1,11 +1,16 @@
static_resources:
# --8<-- [start:listener]
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
# --8<-- [end:listener]
filter_chains:
- filter_chain_match:
server_names: ["*.john-stream.com"]
# --8<-- [start:transport_socket]
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
@@ -13,25 +18,33 @@ static_resources:
require_client_certificate: true
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_3
tls_minimum_protocol_version: TLSv1_3 # (1)!
validation_context:
trusted_ca:
filename: /certs/root_ca.crt
trusted_ca: { filename: /certs/root_ca.crt }
match_typed_subject_alt_names:
- san_type: URI
matcher:
# exact: proxy-postgres-frontend.example.com
exact: spiffe://john-stream.com/ubuntu
prefix: spiffe://john-stream.com # (2)!
tls_certificates:
- certificate_chain:
filename: /certs/cert.pem
private_key:
filename: /certs/envoy.pem
- certificate_chain: { filename: /certs/cert.pem }
private_key: { filename: /certs/key_pkcs8.pem } # (3)!
# --8<-- [end:transport_socket]
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
use_remote_address: true
http2_protocol_options:
max_concurrent_streams: 100
# --8<-- [start:access_log]
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: "/var/log/envoy/access.log"
# --8<-- [end:access_log]
# --8<-- [start:cluster_route]
route_config:
name: local_route
virtual_hosts:
@@ -41,18 +54,64 @@ static_resources:
- match:
prefix: "/"
route:
cluster: rest_server
cluster: restic
# --8<-- [end:cluster_route]
http_filters:
# --8<-- [start:rbac]
- name: envoy.filters.http.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: ALLOW
policies:
"ubuntu-policy":
permissions:
- and_rules:
rules:
- header:
name: ":path"
string_match:
prefix: "/john-ubuntu"
principals:
- authenticated:
principal_name:
exact: "spiffe://john-stream.com/ubuntu"
"p14-policy":
permissions:
- and_rules:
rules:
- header:
name: ":path"
string_match:
prefix: "/john-p14s"
principals:
- authenticated:
principal_name:
exact: "spiffe://john-stream.com/john-p14s"
"gitea-policy":
permissions:
- and_rules:
rules:
- header:
name: ":path"
string_match:
prefix: "/gitea"
principals:
- authenticated:
principal_name:
exact: "spiffe://john-stream.com/gitea"
# --8<-- [end:rbac]
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
# --8<-- [start:cluster]
clusters:
- name: rest_server
- name: restic
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: rest_server
cluster_name: restic
endpoints:
- lb_endpoints:
- endpoint:
@@ -60,3 +119,4 @@ static_resources:
socket_address:
address: rest-server
port_value: 8000
# --8<-- [end:cluster]

View File

@@ -22,9 +22,9 @@ print_status() {
EXIT_CODE=0
CERTS_DIR="$(readlink -f ~/.step/certs)"
SERVER_CERT="$CERTS_DIR/restic.crt"
SERVER_KEY="$CERTS_DIR/restic.key"
CERTS_DIR="/var/lib/tls"
SERVER_CERT="$CERTS_DIR/cert.pem"
SERVER_KEY="$CERTS_DIR/key.pem"
TIMER_NAME="cert-renewer.timer"
# 1. Check Certificates Existence