View this page as Markdown | Gemini
/ _ \ 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