
18 changed files with 393 additions and 97 deletions
@ -1,87 +0,0 @@ |
|||
# use Certbot to automatically generate and renew Let's Encrypt certificates for HAproxy |
|||
|
|||
## Install |
|||
|
|||
install haproxy & certbot: |
|||
``` |
|||
apt install haproxy certbot |
|||
``` |
|||
|
|||
## configure haproxy |
|||
|
|||
we need to configure haproxy to reroute Let's Encrypt requests to the certbot server. Add to your web frontend the directive: |
|||
``` |
|||
frontend www |
|||
bind *:80 |
|||
|
|||
... |
|||
|
|||
# Reroute certbot requests to certbot |
|||
use_backend certbot if { path_beg /.well-known/acme-challenge/ } |
|||
``` |
|||
and also add a backend: |
|||
``` |
|||
backend certbot |
|||
mode http |
|||
server certbot-1 localhost:${port:?} |
|||
``` |
|||
|
|||
and then add an update script to `/usr/local/admin/bin/certbot-haproxy`: |
|||
``` |
|||
#!/bin/bash |
|||
|
|||
create() { |
|||
certbot certonly --standalone -d $1 --non-interactive --agree-tos --email $email --http-01-port=$port |
|||
} |
|||
|
|||
renew() { |
|||
certbot renew --tls-sni-01-port=$port |
|||
} |
|||
|
|||
concat() { |
|||
# Only do the concat if the live cert file is newer than the combined file |
|||
if [[ /etc/letsencrypt/live/$1/fullchain.pem -nt /etc/haproxy/certs/$1.pem ]]; then |
|||
mkdir -p /etc/haproxy/certs |
|||
cat /etc/letsencrypt/live/$1/fullchain.pem /etc/letsencrypt/live/$1/privkey.pem > /etc/haproxy/certs/$1.pem |
|||
#etckeeper commit "got new Let's Encrypt certificate for $1" |
|||
fi |
|||
} |
|||
|
|||
# Main Execution |
|||
if [[ (-z $1) || ("$1" != "create" && "$1" != "renew") ]]; then |
|||
echo "Improper argument: expecting \"create\" or \"renew\"" |
|||
exit 1 |
|||
fi |
|||
|
|||
. /etc/haproxy/certbot.cfg.sh |
|||
|
|||
for site in ${sites[@]}; do |
|||
$1 $site |
|||
concat $site |
|||
done |
|||
``` |
|||
|
|||
and don't forget to make it executable: |
|||
``` |
|||
chmod +x /usr/local/admin/bin/certbot-haproxy |
|||
``` |
|||
|
|||
finally, we will make a config file for our certbot script in `/etc/haproxy/certbot.cfg.sh`: |
|||
``` |
|||
#!/bin/bash |
|||
|
|||
# domains certbot should get certificates for |
|||
sites=( |
|||
medusa.alemor.org |
|||
) |
|||
|
|||
# port that the standalone certbot server should use |
|||
port=8888 |
|||
|
|||
# email that you will give to Let's Encrypt |
|||
email=letsencrypt@mario.alemor.org |
|||
``` |
|||
and make it executable as well: |
|||
``` |
|||
chmod +x /etc/haproxy/certbot.cfg.sh |
|||
``` |
@ -0,0 +1,48 @@ |
|||
# install and configure acme.sh |
|||
|
|||
## install |
|||
|
|||
install `socat`: |
|||
``` |
|||
apt search socat |
|||
``` |
|||
clone git: |
|||
``` |
|||
git clone https://github.com/acmesh-official/acme.sh.git |
|||
``` |
|||
install `acme.sh`: |
|||
``` |
|||
cd acme.sh |
|||
./acme.sh --install --home /usr/local/lib/acme-sh --config-home /etc/acme-sh --accountemail "my@example.com" |
|||
``` |
|||
logout and log back in to make aliases take effect: |
|||
``` |
|||
exit |
|||
sudo -i |
|||
``` |
|||
|
|||
## issue |
|||
|
|||
if you haven't configured haproxy to issue certs with no downtime, you will have to stop and start it. To issue a certificate, run: |
|||
``` |
|||
acme.sh --issue ${protocol:?} --pre-hook "systemctl stop haproxy" --post-hook "systemctl start haproxy" -d ${domain:?} |
|||
``` |
|||
where `protocol` is `--standalone` if you want to use port 80, or `--alpn` if you want to use port 443. |
|||
|
|||
## deploy |
|||
|
|||
once the certificate has been successfully issued, we still have to deploy it to our server. First, make sure the certs path exists, and set the appropriate variables to tell `acme.sh` where to deploy certificates: |
|||
``` |
|||
mkdir -p /etc/haproxy/certs |
|||
export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs |
|||
export DEPLOY_HAPROXY_RELOAD="/usr/sbin/service haproxy reload" |
|||
``` |
|||
finally, deploy the certificate with: |
|||
``` |
|||
acme.sh --deploy -d --deploy-hook haproxy -d ${domain:?} |
|||
``` |
|||
acme.sh should automatically configure reneweal of certificates and deployment of renewed certificates. |
|||
|
|||
## no downtime config |
|||
|
|||
see https://github.com/acmesh-official/acme.sh/wiki/TLS-ALPN-without-downtime |
@ -0,0 +1,81 @@ |
|||
# use Certbot to automatically generate and renew Let's Encrypt certificates for HAproxy |
|||
|
|||
## Install |
|||
|
|||
install haproxy & certbot: |
|||
``` |
|||
apt install haproxy certbot |
|||
``` |
|||
|
|||
## Configure HAproxy HTTP |
|||
|
|||
we need to configure haproxy to reroute Let's Encrypt requests to the certbot server. The beginning of your web frontend should look like: |
|||
``` |
|||
frontend www |
|||
bind *:80 |
|||
option forwardfor |
|||
|
|||
# Reroute certbot requests to certbot |
|||
use_backend certbot if { path_beg /.well-known/acme-challenge/ } |
|||
|
|||
... |
|||
``` |
|||
and also add a backend: |
|||
``` |
|||
backend certbot |
|||
server certbot localhost:8888 |
|||
``` |
|||
|
|||
## Configure Certbot |
|||
|
|||
We also want to configure Certbot so we can easily use it for creating/renewing certificates for HAproxy. Edit the file `/etc/letsencrypt/cli.ini` and add the lines: |
|||
``` |
|||
standalone |
|||
# tls-sni challenge is deprecated |
|||
preferred-challenges = http |
|||
http-01-port = 8888 |
|||
deploy-hook = /etc/letsencrypt/deploy-hook.sh |
|||
``` |
|||
We also need to add the deploy hook script that we referenced in the config file, at `/etc/letsencrypt/deploy-hook.sh`. The contents of the script should be: |
|||
``` |
|||
#!/bin/sh |
|||
|
|||
mkdir -p /etc/haproxy/certs |
|||
base=$(basename $RENEWED_LINEAGE) |
|||
cat $RENEWED_LINEAGE/fullchain.pem $RENEWED_LINEAGE/privkey.pem > /etc/haproxy/certs/$base.pem |
|||
#etckeeper commit "got new Let's Encrypt certificate for $base" |
|||
service haproxy reload |
|||
``` |
|||
(Uncomment the `etckeeper` line if you are using etckeeper to store your configuration). And don't forget to make the script executable: |
|||
``` |
|||
chmod +x /etc/letsencrypt/deploy-hook.sh |
|||
``` |
|||
|
|||
With this configuration, you should be able to run certbot to obtain a certificate. The cron job that is automatically set up when you install certbot will also work correctly with this configuration. |
|||
|
|||
## Get Certificate |
|||
|
|||
Run Certbot to get a certificate: |
|||
``` |
|||
certbot certonly |
|||
``` |
|||
After successfully acquiring a certificate, the deploy hook will automatically put the combined certificate in `/etc/haproxy/certs/` for you. |
|||
|
|||
## Configure HAproxy HTTPs |
|||
|
|||
Now that you have HTTPs working, you can configure HAproxy for HTTPs. The beginning of your web frontend should now look like: |
|||
``` |
|||
frontend www |
|||
bind *:80 |
|||
bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1 |
|||
option forwardfor |
|||
http-request set-header X-Forwarded-Proto https if { ssl_fc } |
|||
|
|||
# Reroute letsencrypt requests to certbot |
|||
use_backend certbot if { path_beg /.well-known/acme-challenge/ } |
|||
|
|||
# Reroute HTTP to HTTPs |
|||
http-request redirect scheme https if !{ ssl_fc } |
|||
|
|||
... |
|||
``` |
@ -0,0 +1,87 @@ |
|||
# use dehydrated to automatically generate and renew Let's Encrypt certificates for HAproxy |
|||
|
|||
## Install |
|||
|
|||
install `curl`: |
|||
``` |
|||
apt install curl |
|||
``` |
|||
download the dehydrated script to `/usr/local/bin`: |
|||
``` |
|||
cd /usr/local/bin/ |
|||
wget https://raw.githubusercontent.com/dehydrated-io/dehydrated/master/dehydrated |
|||
chmod +x dehydrated |
|||
``` |
|||
|
|||
## Configure HAproxy HTTP |
|||
|
|||
we need to configure haproxy to reroute Let's Encrypt requests to the certbot server. The beginning of your web frontend should look like: |
|||
``` |
|||
frontend www |
|||
bind *:80 |
|||
option forwardfor |
|||
|
|||
# Reroute certbot requests to certbot |
|||
use_backend certbot if { path_beg /.well-known/acme-challenge/ } |
|||
|
|||
... |
|||
``` |
|||
and also add a backend: |
|||
``` |
|||
backend certbot |
|||
server certbot localhost:8888 |
|||
``` |
|||
|
|||
## Configure Certbot |
|||
|
|||
We also want to configure Certbot so we can easily use it for creating/renewing certificates for HAproxy. Edit the file `/etc/letsencrypt/cli.ini` and add the lines: |
|||
``` |
|||
standalone |
|||
# tls-sni challenge is deprecated |
|||
preferred-challenges = http |
|||
http-01-port = 8888 |
|||
deploy-hook = /etc/letsencrypt/deploy-hook.sh |
|||
``` |
|||
We also need to add the deploy hook script that we referenced in the config file, at `/etc/letsencrypt/deploy-hook.sh`. The contents of the script should be: |
|||
``` |
|||
#!/bin/sh |
|||
|
|||
mkdir -p /etc/haproxy/certs |
|||
base=$(basename $RENEWED_LINEAGE) |
|||
cat $RENEWED_LINEAGE/fullchain.pem $RENEWED_LINEAGE/privkey.pem > /etc/haproxy/certs/$base.pem |
|||
#etckeeper commit "got new Let's Encrypt certificate for $base" |
|||
service haproxy reload |
|||
``` |
|||
(Uncomment the `etckeeper` line if you are using etckeeper to store your configuration). And don't forget to make the script executable: |
|||
``` |
|||
chmod +x /etc/letsencrypt/deploy-hook.sh |
|||
``` |
|||
|
|||
With this configuration, you should be able to run certbot to obtain a certificate. The cron job that is automatically set up when you install certbot will also work correctly with this configuration. |
|||
|
|||
## Get Certificate |
|||
|
|||
Run Certbot to get a certificate: |
|||
``` |
|||
certbot certonly |
|||
``` |
|||
After successfully acquiring a certificate, the deploy hook will automatically put the combined certificate in `/etc/haproxy/certs/` for you. |
|||
|
|||
## Configure HAproxy HTTPs |
|||
|
|||
Now that you have HTTPs working, you can configure HAproxy for HTTPs. The beginning of your web frontend should now look like: |
|||
``` |
|||
frontend www |
|||
bind *:80 |
|||
bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1 |
|||
option forwardfor |
|||
http-request set-header X-Forwarded-Proto https if { ssl_fc } |
|||
|
|||
# Reroute letsencrypt requests to certbot |
|||
use_backend certbot if { path_beg /.well-known/acme-challenge/ } |
|||
|
|||
# Reroute HTTP to HTTPs |
|||
http-request redirect scheme https if !{ ssl_fc } |
|||
|
|||
... |
|||
``` |
@ -0,0 +1,27 @@ |
|||
# Customize your login message (MOTD) |
|||
|
|||
## Static MOTD |
|||
|
|||
If you just want to print a static message, put it in `/etc/motd`. |
|||
|
|||
## Dynamic MOTD |
|||
|
|||
If you want to print a dynamic message, it gets a bit more complicated. |
|||
|
|||
### Disable other MOTD methods |
|||
|
|||
First, make sure to disable other ways via which the MOTD is set. |
|||
|
|||
Make sure the MOTD service is disabled: |
|||
``` |
|||
systemctl disable motd |
|||
``` |
|||
|
|||
Delete the static motd file: |
|||
``` |
|||
rm /etc/motd |
|||
``` |
|||
|
|||
### configure dynamic scripts |
|||
|
|||
The dynamic MOTD is printed by executing the scripts in `/etc/update-motd.d`, in numerical/alphabetical order. Simply put any scripts you want to be run in there. |
@ -0,0 +1,11 @@ |
|||
#!/bin/bash |
|||
|
|||
echo "Welcome to $(hostname)" |
|||
echo "$(date)" |
|||
echo "$(lsb_release -sd) $(uname -rm)" |
|||
upgrades=$(apt list -qq --upgradable 2> /dev/null | wc -l) |
|||
if [[ $upgrades == 0 ]]; then |
|||
printf "All packages are up to date.\n\n" |
|||
else |
|||
printf "$upgrades packages can be upgraded. Run 'apt list --upgradable' to see them.\n\n" |
|||
fi |
@ -0,0 +1,18 @@ |
|||
#!/bin/bash |
|||
|
|||
echo "System:" |
|||
echo " Uptime: $(uptime -p | cut -d' ' -f2-) (up since $(uptime -s))" |
|||
echo " Memory: $(free -h | grep Mem | perl -pe 's/Mem:\s+([\.\w]+)\s+([\.\w]+)\s+([\.\w]+).*/\1 total, |
|||
\2 used, \3 free/')" |
|||
echo " Swap: $(free -h | grep Swap | perl -pe 's/Swap:\s+([\.\w]+)\s+([\.\w]+)\s+([\.\w]+).*/\1 tota |
|||
l, \2 used, \3 free/')" |
|||
echo " Load Avg: $(cat /proc/loadavg | cut -d' ' -f1-3 | perl -pe 's/([\.\d]+) ([\.\d]+) ([\.\d]+)/\1 (a |
|||
vg 1 min), \2 (avg 5 min), \3 (avg 15 min)/')" |
|||
users=$(w | tail -n +3 | cut -d' ' -f1 | sort | uniq -c | wc -l) |
|||
sessions=$(w | tail -n +3 | wc -l) |
|||
echo " Logins: $users users with $sessions sessions total" |
|||
ip=$(ip -4 addr show wan0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') |
|||
name=$(host $ip | cut -d' ' -f5) |
|||
name=${name%?} |
|||
echo " WAN Addr: $ip (hostname $name)" |
|||
echo "" |
@ -0,0 +1,5 @@ |
|||
#!/bin/bash |
|||
|
|||
echo "ZFS Pools:" |
|||
echo " $(zpool status -x)" |
|||
echo "" |
@ -0,0 +1,31 @@ |
|||
# podman cheat sheet |
|||
|
|||
show running containers: |
|||
``` |
|||
podman ps |
|||
``` |
|||
|
|||
show images: |
|||
``` |
|||
podman images |
|||
``` |
|||
|
|||
build image: |
|||
``` |
|||
podman build -f Containerfile -t localhost/nextcloud:latest -t localhost/nextcloud:$today |
|||
``` |
|||
|
|||
create container: |
|||
``` |
|||
podman create --name nextcloud localhost/nextcloud |
|||
``` |
|||
|
|||
get container IP: |
|||
``` |
|||
podman inspect -f '{{ .NetworkSettings.IPAddress }}' nextcloud |
|||
``` |
|||
|
|||
log into container shell: |
|||
``` |
|||
podman exec -it nextcloud bash |
|||
``` |
@ -0,0 +1,41 @@ |
|||
# install and configure Podman for running rootless containers |
|||
|
|||
## add repo and install |
|||
|
|||
Podman is being packaged natively for Debian, but hasn't yet. For now, install it from the repo being hosted by the Kubic project: |
|||
``` |
|||
echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/podman.list |
|||
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/Release.key | apt-key add - |
|||
apt update |
|||
apt install podman fuse-overlayfs slirp4netns |
|||
``` |
|||
|
|||
## configure system |
|||
|
|||
configure subuids & subgids. Add the lines: |
|||
``` |
|||
root:1000000:1000000000 |
|||
root:60000:1 |
|||
``` |
|||
to `/etc/subuid` and `/etc/subgid`. |
|||
|
|||
## configure podman |
|||
|
|||
the default runtime `runc` does not support cgroup V2, so you need to change the runtime to be the alternative OCI runtime `crun`. Edit or create the file `/etc/containers/libpod.conf` and add the lines: |
|||
``` |
|||
# Use alternative runtime with cgroup V2 support |
|||
runtime = "crun" |
|||
``` |
|||
|
|||
|
|||
podman build -t systemd |
|||
podman run --cgroupsns=private -ti -p 80:80 systemd |
|||
--uidmap 0:10000:5000 |
|||
--userns=auto |
|||
|
|||
containerfile: |
|||
FROM debian:10 |
|||
|
|||
install systemd |
|||
|
|||
CMD [ "/sbin/init" ] |
@ -0,0 +1,5 @@ |
|||
# set a user's password empty but required to be immediately set on login |
|||
|
|||
``` |
|||
passwd -d -e ${user:?} |
|||
``` |
@ -1,3 +1,3 @@ |
|||
# Find package that owns a certain file |
|||
grep «filename» /var/lib/dpkg/info/*.list |
|||
grep "${filename:?}" /var/lib/dpkg/info/*.list |
|||
|
|||
|
@ -0,0 +1,5 @@ |
|||
# mark an APT package as autoinstalled |
|||
|
|||
``` |
|||
apt-mark auto ${package_name:?} |
|||
``` |
Loading…
Reference in new issue