Home | Markdown | Gemini | Microblog
/ _ \
The Hebern Machine \ ." ". /
___ / \
.."" "".. | O |
/ \ | |
/ \ | |
---------------------------------
_/ o (O) o _ |
_/ ." ". |
I/ _________________/ \ |
_/I ." | |
===== / I / / |
===== | | | \ | _________________." |
===== | | | | | / \ / _|_|__|_|_ __ |
| | | | | | | \ "._." / o o \ ." ". |
| --| --| -| / \ _/ / \ |
\____\____\__| \ ______ | / | | |
-------- --- / | | |
( ) (O) / \ / |
----------------------- ".__." |
_|__________________________________________|_
/ \
/________________________________________________\
ASCII Art by John Savard
#
# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
#
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
authority buypass {
api url "https://api.buypass.com/acme/directory"
account key "/etc/acme/buypass-privkey.pem"
contact "mailto:me@example.com"
}
authority buypass-test {
api url "https://api.test4.buypass.no/acme/directory"
account key "/etc/acme/buypass-test-privkey.pem"
contact "mailto:me@example.com"
}
domain buetow.org {
alternative names { www.buetow.org paul.buetow.org }
domain key "/etc/ssl/private/buetow.org.key"
domain full chain certificate "/etc/ssl/buetow.org.fullchain.pem"
sign with letsencrypt
}
domain dtail.dev {
alternative names { www.dtail.dev }
domain key "/etc/ssl/private/dtail.dev.key"
domain full chain certificate "/etc/ssl/dtail.dev.fullchain.pem"
sign with letsencrypt
}
domain foo.zone {
alternative names { www.foo.zone }
domain key "/etc/ssl/private/foo.zone.key"
domain full chain certificate "/etc/ssl/foo.zone.fullchain.pem"
sign with letsencrypt
}
domain irregular.ninja {
alternative names { www.irregular.ninja }
domain key "/etc/ssl/private/irregular.ninja.key"
domain full chain certificate "/etc/ssl/irregular.ninja.fullchain.pem"
sign with letsencrypt
}
domain snonux.land {
alternative names { www.snonux.land }
domain key "/etc/ssl/private/snonux.land.key"
domain full chain certificate "/etc/ssl/snonux.land.fullchain.pem"
sign with letsencrypt
}
server "foo.zone" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location * {
block return 302 "https://$HTTP_HOST$REQUEST_URI"
}
}
server "foo.zone" {
listen on * tls port 443
tls {
certificate "/etc/ssl/foo.zone.fullchain.pem"
key "/etc/ssl/private/foo.zone.key"
}
location * {
root "/htdocs/gemtexter/foo.zone"
directory auto index
}
}
#!/bin/sh
function handle_cert {
host=$1
# Create symlink, so that relayd also can read it.
crt_path=/etc/ssl/$host
if [ -e $crt_path.crt ]; then
rm $crt_path.crt
fi
ln -s $crt_path.fullchain.pem $crt_path.crt
# Requesting and renewing certificate.
/usr/sbin/acme-client -v $host
}
has_update=no
handle_cert www.buetow.org
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.paul.buetow.org
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.tmp.buetow.org
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.dtail.dev
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.foo.zone
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.irregular.ninja
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.snonux.land
if [ $? -eq 0 ]; then
has_update=yes
fi
# Pick up the new certs.
if [ $has_update = yes ]; then
/usr/sbin/rcctl reload httpd
/usr/sbin/rcctl reload relayd
/usr/sbin/rcctl restart smtpd
fi
/usr/local/bin/acme.sh
Running daily.local: acme-client: /etc/ssl/buetow.org.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/paul.buetow.org.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/tmp.buetow.org.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/dtail.dev.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/foo.zone.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/irregular.ninja.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/snonux.land.fullchain.pem: certificate valid: 79 days left
our @acme_hosts = qw/buetow.org paul.buetow.org tmp.buetow.org dtail.dev foo.zone irregular.ninja snonux.land/;
group frontends => 'blowfish.buetow.org', 'twofish.buetow.org';
desc 'Configure ACME client';
task 'acme', group => 'frontends',
sub {
file '/etc/acme-client.conf',
content => template('./etc/acme-client.conf.tpl',
acme_hosts => \@acme_hosts,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '644';
file '/usr/local/bin/acme.sh',
content => template('./scripts/acme.sh.tpl',
acme_hosts => \@acme_hosts,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '744';
file '/etc/daily.local',
ensure => 'present',
owner => 'root',
group => 'wheel',
mode => '644';
append_if_no_such_line '/etc/daily.local', '/usr/local/bin/acme.sh';
};
desc 'Invoke ACME client';
task 'acme_invoke', group => 'frontends',
sub {
say run '/usr/local/bin/acme.sh';
};
# Bootstrapping the FQDN based on the server IP as the hostname and domain
# facts aren't set yet due to the myname file in the first place.
our $fqdns = sub {
my $ipv4 = shift;
return 'blowfish.buetow.org' if $ipv4 eq '23.88.35.144';
return 'twofish.buetow.org' if $ipv4 eq '108.160.134.135';
Rex::Logger::info("Unable to determine hostname for $ipv4", 'error');
return 'HOSTNAME-UNKNOWN.buetow.org';
};
# To determine whether the server is the primary or the secondary.
our $is_primary = sub {
my $ipv4 = shift;
$fqdns->($ipv4) eq 'blowfish.buetow.org';
};
#
# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
#
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
authority buypass {
api url "https://api.buypass.com/acme/directory"
account key "/etc/acme/buypass-privkey.pem"
contact "mailto:me@example.com"
}
authority buypass-test {
api url "https://api.test4.buypass.no/acme/directory"
account key "/etc/acme/buypass-test-privkey.pem"
contact "mailto:me@example.com"
}
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
%>
<% for my $host (@$acme_hosts) { %>
domain <%= $prefix.$host %> {
domain key "/etc/ssl/private/<%= $prefix.$host %>.key"
domain full chain certificate "/etc/ssl/<%= $prefix.$host %>.fullchain.pem"
sign with letsencrypt
}
<% } %>
#!/bin/sh
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
-%>
function handle_cert {
host=$1
# Create symlink, so that relayd also can read it.
crt_path=/etc/ssl/$host
if [ -e $crt_path.crt ]; then
rm $crt_path.crt
fi
ln -s $crt_path.fullchain.pem $crt_path.crt
# Requesting and renewing certificate.
/usr/sbin/acme-client -v $host
}
has_update=no
<% for my $host (@$acme_hosts) { -%>
handle_cert <%= $prefix.$host %>
if [ $? -eq 0 ]; then
has_update=yes
fi
<% } -%>
# Pick up the new certs.
if [ $has_update = yes ]; then
/usr/sbin/rcctl reload httpd
/usr/sbin/rcctl reload relayd
/usr/sbin/rcctl restart smtpd
fi
desc 'Setup httpd';
task 'httpd', group => 'frontends',
sub {
append_if_no_such_line '/etc/rc.conf.local', 'httpd_flags=';
file '/etc/httpd.conf',
content => template('./etc/httpd.conf.tpl',
acme_hosts => \@acme_hosts,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'httpd' => 'restart' };
service 'httpd', ensure => 'started';
};
desc 'Setup relayd';
task 'relayd', group => 'frontends',
sub {
append_if_no_such_line '/etc/rc.conf.local', 'relayd_flags=';
file '/etc/relayd.conf',
content => template('./etc/relayd.conf.tpl',
ipv6address => $ipv6address,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '600',
on_change => sub { service 'relayd' => 'restart' };
service 'relayd', ensure => 'started';
};
desc 'Setup OpenSMTPD';
task 'smtpd', group => 'frontends',
sub {
Rex::Logger::info('Dealing with mail aliases');
file '/etc/mail/aliases',
source => './etc/mail/aliases',
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { say run 'newaliases' };
Rex::Logger::info('Dealing with mail virtual domains');
file '/etc/mail/virtualdomains',
source => './etc/mail/virtualdomains',
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'smtpd' => 'restart' };
Rex::Logger::info('Dealing with mail virtual users');
file '/etc/mail/virtualusers',
source => './etc/mail/virtualusers',
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'smtpd' => 'restart' };
Rex::Logger::info('Dealing with smtpd.conf');
file '/etc/mail/smtpd.conf',
content => template('./etc/mail/smtpd.conf.tpl',
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'smtpd' => 'restart' };
service 'smtpd', ensure => 'started';
};
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
%>
# Plain HTTP for ACME and HTTPS redirect
<% for my $host (@$acme_hosts) { %>
server "<%= $prefix.$host %>" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location * {
block return 302 "https://$HTTP_HOST$REQUEST_URI"
}
}
<% } %>
# Gemtexter hosts
<% for my $host (qw/foo.zone snonux.land/) { %>
server "<%= $prefix.$host %>" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix.$host %>.fullchain.pem"
key "/etc/ssl/private/<%= $prefix.$host %>.key"
}
location * {
root "/htdocs/gemtexter/<%= $host %>"
directory auto index
}
}
<% } %>
# DTail special host
server "<%= $prefix %>dtail.dev" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>dtail.dev.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>dtail.dev.key"
}
location * {
block return 302 "https://github.dtail.dev$REQUEST_URI"
}
}
# Irregular Ninja special host
server "<%= $prefix %>irregular.ninja" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>irregular.ninja.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>irregular.ninja.key"
}
location * {
root "/htdocs/irregular.ninja"
directory auto index
}
}
# buetow.org special host.
server "<%= $prefix %>buetow.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>buetow.org.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>buetow.org.key"
}
block return 302 "https://paul.buetow.org"
}
server "<%= $prefix %>paul.buetow.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>paul.buetow.org.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>paul.buetow.org.key"
}
block return 302 "https://foo.zone/contact-information.html"
}
server "<%= $prefix %>tmp.buetow.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>tmp.buetow.org.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>tmp.buetow.org.key"
}
root "/htdocs/buetow.org/tmp"
directory auto index
}
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
%>
log connection
tcp protocol "gemini" {
tls keypair <%= $prefix %>foo.zone
tls keypair <%= $prefix %>buetow.org
}
relay "gemini4" {
listen on <%= $vio0_ip %> port 1965 tls
protocol "gemini"
forward to 127.0.0.1 port 11965
}
relay "gemini6" {
listen on <%= $ipv6address->($hostname) %> port 1965 tls
protocol "gemini"
forward to 127.0.0.1 port 11965
}
<% our $primary = $is_primary->($vio0_ip); our $prefix = $primary ? '' : 'www.'; %> pki "buetow_org_tls" cert "/etc/ssl/<%= $prefix %>buetow.org.fullchain.pem" pki "buetow_org_tls" key "/etc/ssl/private/<%= $prefix %>buetow.org.key" table aliases file:/etc/mail/aliases table virtualdomains file:/etc/mail/virtualdomains table virtualusers file:/etc/mail/virtualusers listen on socket listen on all tls pki "buetow_org_tls" hostname "<%= $prefix %>buetow.org" #listen on all action localmail mbox alias <aliases> action receive mbox virtual <virtualusers> action outbound relay match from any for domain <virtualdomains> action receive match from local for local action localmail match from local for any action outbound
rex commons