Blame


1 aa513bf8 2023-01-22 jrmu version=pmwiki-2.2.130 ordered=1 urlencoded=1
2 aa513bf8 2023-01-22 jrmu agent=w3m/0.5.3+git20210102
3 aa513bf8 2023-01-22 jrmu author=jrmu
4 aa513bf8 2023-01-22 jrmu charset=UTF-8
5 aa513bf8 2023-01-22 jrmu csum=
6 aa513bf8 2023-01-22 jrmu ctime=1614076701
7 aa513bf8 2023-01-22 jrmu host=38.87.162.154
8 aa513bf8 2023-01-22 jrmu name=Acme-client.Configure
9 aa513bf8 2023-01-22 jrmu rev=59
10 aa513bf8 2023-01-22 jrmu targets=Openhttpd.Configure,Dns.Overview,Host.Usage,Netcat.Http,Crontab.Edit,Nsd.Troubleshoot,Telnet.Http,Openssl.Http
11 aa513bf8 2023-01-22 jrmu text=(:title Configuring Acme-client:)%0a%0aTo enable TLS, you will want a certificate signed by a trusted certificate authority (CA). In this guide, we'll use OpenBSD's [[https://man.openbsd.org/acme-client|acme-client]] with Let's Encrypt.%0a%0a!! Overview%0a%0aTLS (Transport Layer Security) aka SSL (Secure Sockets Layer) is the encryption security measure that enables browsers to recognize a website as "secure". In modern browsers the SSL information can be accessed by clicking the padlock icon in the address bar. %0a%0aSSL certificates are obtained from CAs (Certificate Authorities). Currently, the only free CAs are [[https://letsencrypt.org/getting-started/ | Lets Encrypt]], [[https://www.buypass.com/ssl/products/acme | Buypass]] and [[https://zerossl.com/ | ZeroSSL]]. You can request an SSL cert for your web domain using an Automatic Certificate Management Environment (ACME) client such as OpenBSD's Acme-client, which we will configure in this article.%0a%0a!!! Before You Begin %0a%0aYou will first need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need properly functioning [[dns/overview|DNS records]] for your hostname (@@username.example.com@@). If you are using a training vps, it is likely that DNS records for your hostname have already been set up for you.%0a%0aYou can and should test the two configurations using [[host/usage|host]] and [[netcat/http|netcat]].%0a%0aNote: You must have a server block in [[https://man.openbsd.org/httpd.conf|/etc/httpd.conf]] listening on port 80. Do not delete this block or else acme-client will not work.%0a%0a!! Configuration%0a%0aFirst, copy the [[https://man.openbsd.org/acme-client.conf|acme-client.conf]] template:%0a%0a[@%0a$ doas cp /etc/examples/acme-client.conf /etc/acme-client.conf%0a@]%0a%0aWe'll open up [@ /etc/acme-client.conf @] and analyze the meaning of each block:%0a%0a!!! Authority blocks%0a%0a[@%0aauthority letsencrypt {%0a api url "https://acme-v02.api.letsencrypt.org/directory"%0a account key "/etc/acme/letsencrypt-privkey.pem"%0a}%0a@]%0a%0aThis defines the Certificate Authority [[https://letsencrypt.org/|letsencrypt]]. It provides the API URL and the location of the account key.%0a%0a'''Note''': Let's Encrypt [[https://letsencrypt.org/docs/rate-limits/|rate-limits]] the number of SSL certs you can request. If you encounter an error and are unable to request an SSL cert, please fix all errors before requesting again. If you request too many certs in a short time, your domain will get blacklisted for a few hours or days. To avoid issues, use letsencrypt-staging first and make sure you get success with that before using letsencrypt.%0a%0aAlthough we are using Let's Encrypt for this tutorial, it is important to note that having the majority of servers depend upon a single provider is dangerous. For this reason, it would be beneficial to someday have the community run its own Certificate Authority to avoid censorship of domains or other security issues.%0a%0a[@%0aauthority letsencrypt-staging {%0a api url "https://acme-staging-v02.api.letsencrypt.org/directory"%0a account key "/etc/acme/letsencrypt-staging-privkey.pem"%0a}%0a@]%0a%0aletsencrypt-staging is a staging server which you can use to practice requesting fake certificates. The rate limits for the staging server are less strict, so you should practice first with this CA.%0a%0aTo both of these blocks, we will want to add our contact email, so we add [@contact "mailto:me@example.com" @] inside both blocks. (make sure to have the @@mailto:@@):%0a%0a[@%0aauthority letsencrypt {%0a api url "https://acme-v02.api.letsencrypt.org/directory"%0a account key "/etc/acme/letsencrypt-privkey.pem"%0a contact "mailto:me@example.com"%0a}%0a%0aauthority letsencrypt-staging {%0a api url "https://acme-staging-v02.api.letsencrypt.org/directory"%0a account key "/etc/acme/letsencrypt-staging-privkey.pem"%0a contact "mailto:me@example.com"%0a}%0a@]%0a%0aNext, the default [[https://man.openbsd.org/acme-client.conf|acme-client.conf]] defines two more authorities:%0a%0a[@%0aauthority buypass {%0a api url "https://api.buypass.com/acme/directory"%0a account key "/etc/acme/buypass-privkey.pem"%0a contact "mailto:me@example.com"%0a}%0a%0aauthority buypass-test {%0a api url "https://api.test4.buypass.no/acme/directory"%0a account key "/etc/acme/buypass-test-privkey.pem"%0a contact "mailto:me@example.com"%0a}%0a@]%0a%0aThese two blocks are the same as for letsencrypt, but with the alternative provider [[https://buypass.com/|buypass]]. Make sure to replace the contact email with your own email.%0a%0a!!! Domain Block%0a%0a[@%0adomain example.com {%0a alternative names { secure.example.com }%0a domain key "/etc/ssl/private/example.com.key"%0a domain full chain certificate "/etc/ssl/example.com.crt"%0a sign with letsencrypt%0a}%0a@]%0a%0aFirst, replace every appearance of @@example.com@@ with your own domain.%0a%0aEach SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@example.com@@ and the alternative names @@www.example.com@@ and @@mail.example.com@@. You can safely skip this by commenting out this line (see warning below)%0a%0aIf you use too many alternative names, an acme-client certificate request has a higher chance of failure. So, we recommend keeping the number of alternative names to under 5.%0a%0a'''Warning''': Having the @@alternative names@@ directive with nothing inside will cause errors. For example, the below will cause errors:%0a%0a[@%0aalternative names { }%0a@]%0a%0aIf you don't need any alternative names, you should comment this line out by putting a # at the beginning of the line, like so:%0a%0a[@%0a# alternative names { }%0a@]%0a%0a'''Note''': If you add an alternative name to the conf file, but the cert already exists, you must remove the old public cert first before requesting a new one. Otherwise, you will get @@unknown SAN error@@ -- acme-client will complain there is an unknown '''Subject Alternative Name'''.%0a%0aNext, the @@domain key@@ and @@domain full chain certificate@@ tell acme-client where to put the private key and certificate:%0a%0a[@%0a domain key "/etc/ssl/private/example.com.key"%0a domain full chain certificate "/etc/ssl/example.com.crt"%0a@]%0a%0aThe public key goes inside the folder @@/etc/ssl@@ and the private key goes inside @@/etc/ssl/private@@.%0a%0aThe line @@sign with letsencrypt@@ line tells Acme-client which Certificate Authority (which you defined in the Authority Blocks) to use.%0a%0aFor testing purposes, you may want to change it to @@letsencrypt-staging@@. You can also consider using @@buypass@@ or @@buypass-test@@.%0a%0a'''Note''': staging or testing certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, change this line back to an official authority (such as @@sign with letsencrypt@@).%0a%0a!! Requesting Certificates%0a%0aAfter you have finished configuring the conf file, we can request certificates:%0a%0a[@%0a$ doas acme-client -Fv example.com%0a@]%0a%0aIf there are no errors, you should see something similar to the following output:%0a%0a[@%0a$ doas acme-client -Fv example.com%0aacme-client: /etc/acme/letsencrypt-privkey.pem: generated RSA account key%0aacme-client: /etc/ssl/private/example.com.key: generated RSA domain key%0aacme-client: https://acme-v02.api.letsencrypt.org/directory: directories%0aacme-client: acme-v02.api.letsencrypt.org: DNS: 172.65.32.248%0aacme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/11133258838%0aacme-client: challenge, token: uWHZmqhx6NEpcv25LEvodMAeymB1guTFVtyktVzkJgs, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/11133258838/_UI3-A, status: 0%0aacme-client: /var/www/acme/uWHZmqhx6NEpcv25LEvodMAeymB1guTFVtyktVzkJgs: created%0aacme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/11133258838/_UI3-A: challenge%0aacme-client: order.status 0%0aacme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/11133258838%0aacme-client: challenge, token: uWHZmqhx6NEpcv25LEvodMAeymB1guTFVtyktVzkJgs, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/11133258838/_UI3-A, status: 2%0aacme-client: order.status 1%0aacme-client: https://acme-v02.api.letsencrypt.org/acme/finalize/113861127/8112730231: certificate%0aacme-client: order.status 3%0aacme-client: https://acme-v02.api.letsencrypt.org/acme/cert/03f7fd846802cb0689c2bbd7b6f5e89eb66b: certificate%0aacme-client: /etc/ssl/example.com.crt: created%0a@]%0a%0aThe last line says that the public certificate was generated. If you see that, it's a success!%0a%0aYou now have two certificates, the public key inside @@/etc/ssl/example.com.crt@@, and the private key inside @@/etc/ssl/private/example.com.key@@:%0a%0a[@%0a$ doas ls -l /etc/ssl/example.com.crt /etc/ssl/private/example.com.key%0a-r--r--r-- 1 root wheel 4797 Feb 25 02:11 /etc/ssl/example.com.crt%0a-r-------- 1 root wheel 3272 Feb 25 02:10 /etc/ssl/private/example.com.key%0a@]%0a%0a!! Automation%0a%0aLet's Encrypt TLS certs expire after 90 days, while Buypass certs expire after 180. For both, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/edit|crontab]].%0a%0a[@%0a$ doas crontab -e%0a@]%0a%0aAdd this line at the bottom:%0a%0a[@%0a~ ~ * * * acme-client example.com >> /var/log/acme-client.log 2>&1%0a@]%0a%0aThis cronjob will check the certificate once each day, at a random time of day, to see if it needs to be renewed. If it does, it will renew the cert.%0a%0a!! Troubleshooting%0a%0aIf acme-client fails, there are several possible causes:%0a%0a!!! Domain Not Listed%0a%0aIf you add a new alternative name inside your domain block in [[https://man.openbsd.org/acme-client.conf|/etc/acme-client.conf]], you will see this error:%0a %0a[@%0aacme-client: /etc/ssl/example.com.crt: domain not listed: new.example.com%0a@]%0a%0aHere, @@new.example.com@@ was a new alternative name you added. The solution is to move your old public cert and private key to a new location (to back it up). Then, request the cert again.%0a%0a[@%0a$ doas mv /etc/ssl/example.com.crt /etc/ssl/example.com.crt.bak%0a$ doas mv /etc/ssl/private/example.com.key /etc/ssl/private/example.com.key.bak%0a@]%0a%0aThen request the cert again:%0a%0a[@%0a$ doas acme-client -Fv example.com%0a@]%0a%0a!!! Missing Domain Records%0a%0aIt's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a%0a[@%0a$ host example.com%0a@]%0a%0aYou should see one or two records like the following:%0a%0a[@%0aexample.com has address 93.184.216.34%0aexample.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a@]%0a%0aIf you have missing records, you will see this response:%0a%0a[@%0aHost example.com not found: 3(NXDOMAIN)%0a@]%0a%0aYou will either need to speak with your DNS provider or troubleshoot [[nsd/troubleshoot|nsd]]. If DNS records are missing or incorrect, fix these first.%0a%0aThe IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on. If they do not match, you must fix this.%0a%0a'''Note''': You '''cannot''' request a domain you don't own! The domain must point to an IP you own.%0a%0aLastly, if your DNS record includes an IPv6 address, make sure your web server is listening on IPv6. If the DNS record contains an IPv4 address, make sure your web server is listening on IPv4.%0a%0a!!! OpenHTTPd Misconfigured%0a%0aIf [[openhttpd/configure|openhttpd]] is not configured and running properly, acme-client won't work.%0a%0a(acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. )%0a%0aTo test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain) on another computer.%0a%0a[@%0a$ telnet example.com 80%0aGET /index.html HTTP/1.1%0aHost: example.com%0a@]%0a%0aIf you do not get the correct response, double check your [[openhttpd/configure|openhttpd configuration]].%0a%0a'''Note''': Although a web browser can also be used for testing, many web browsers automatically forward all port 80 requests to port 443. As a result, your web browser will only see what is listening on port 443, whereas the certificate authority tests port 80 only.%0a%0a!!! Incorrect File Permissions%0a%0aDouble check @@/var/www@@ and @@/var/www/acme@@ for correct file permissions:%0a%0a[@%0a$ ls -ld /var/www /var/www/acme%0adrwxr-xr-x 10 root daemon 512 Oct 5 07:47 /var/www%0adrwxr-xr-x 2 root daemon 512 Oct 5 07:47 /var/www/acme%0a@]%0a%0aSee Also:%0a%0a|| border=1 width=100%25 class="sortable simpletable"%0a|| [[openhttpd/configure|Configure OpenHTTPd]] || Configure HTTPd ||%0a|| [[telnet/http|Telnet HTTP]] || Use Telnet to Troubleshoot HTTP ||%0a|| [[openssl/http|OpenSSL HTTP]] || Use OpenSSL to Troubleshoot HTTPS ||%0a
12 aa513bf8 2023-01-22 jrmu time=1655193716
13 aa513bf8 2023-01-22 jrmu title=Configuring Acme-client
14 aa513bf8 2023-01-22 jrmu author:1655193716=jrmu
15 aa513bf8 2023-01-22 jrmu diff:1655193716:1655192828:=173,176c173,180%0a%3c !! Automation%0a%3c %0a%3c Let's Encrypt TLS certs expire after 90 days, while Buypass certs expire after 180. For both, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/edit|crontab]].%0a%3c %0a---%0a> !! Troubleshooting%0a> %0a> If acme-client fails, there are several possible causes:%0a> %0a> !!! Domain Not Listed%0a> %0a> If you add a new alternative name inside your domain block in [[https://man.openbsd.org/acme-client.conf|/etc/acme-client.conf]], you will see this error:%0a> %0a178c182%0a%3c $ doas crontab -e%0a---%0a> acme-client: /etc/ssl/example.com.crt: domain not listed: new.example.com%0a181,182c185,186%0a%3c Add this line at the bottom:%0a%3c %0a---%0a> Here, @@new.example.com@@ was a new alternative name you added. The solution is to move your old public cert and private key to a new location (to back it up). Then, request the cert again.%0a> %0a184c188,189%0a%3c ~ ~ * * * acme-client example.com >> /var/log/acme-client.log 2>&1%0a---%0a> $ doas mv /etc/ssl/example.com.crt /etc/ssl/example.com.crt.bak%0a> $ doas mv /etc/ssl/private/example.com.key /etc/ssl/private/example.com.key.bak%0a187,196c192,193%0a%3c This cronjob will check the certificate once each day, at a random time of day, to see if it needs to be renewed. If it does, it will renew the cert.%0a%3c %0a%3c !! Troubleshooting%0a%3c %0a%3c If acme-client fails, there are several possible causes:%0a%3c %0a%3c !!! Domain Not Listed%0a%3c %0a%3c If you add a new alternative name inside your domain block in [[https://man.openbsd.org/acme-client.conf|/etc/acme-client.conf]], you will see this error:%0a%3c %0a---%0a> Then request the cert again:%0a> %0a198c195%0a%3c acme-client: /etc/ssl/example.com.crt: domain not listed: new.example.com%0a---%0a> $ doas acme-client -Fv example.com%0a201,202c198,201%0a%3c Here, @@new.example.com@@ was a new alternative name you added. The solution is to move your old public cert and private key to a new location (to back it up). Then, request the cert again.%0a%3c %0a---%0a> !!! Missing Domain Records%0a> %0a> It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a> %0a204,205c203%0a%3c $ doas mv /etc/ssl/example.com.crt /etc/ssl/example.com.crt.bak%0a%3c $ doas mv /etc/ssl/private/example.com.key /etc/ssl/private/example.com.key.bak%0a---%0a> $ host example.com%0a208,209c206,207%0a%3c Then request the cert again:%0a%3c %0a---%0a> You should see one or two records like the following:%0a> %0a211c209,210%0a%3c $ doas acme-client -Fv example.com%0a---%0a> example.com has address 93.184.216.34%0a> example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a214,217c213,214%0a%3c !!! Missing Domain Records%0a%3c %0a%3c It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a%3c %0a---%0a> If you have missing records, you will see this response:%0a> %0a219c216%0a%3c $ host example.com%0a---%0a> Host example.com not found: 3(NXDOMAIN)%0a222,234d218%0a%3c You should see one or two records like the following:%0a%3c %0a%3c [@%0a%3c example.com has address 93.184.216.34%0a%3c example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a%3c @]%0a%3c %0a%3c If you have missing records, you will see this response:%0a%3c %0a%3c [@%0a%3c Host example.com not found: 3(NXDOMAIN)%0a%3c @]%0a%3c %0a249,250c233,234%0a%3c To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain) on another computer.%0a%3c %0a---%0a> To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain) from another computer:%0a> %0a257,264c241,242%0a%3c If you do not get the correct response, double check your [[openhttpd/configure|openhttpd configuration]].%0a%3c %0a%3c '''Note''': Although a web browser can also be used for testing, many web browsers automatically forward all port 80 requests to port 443. As a result, your web browser will only see what is listening on port 443, whereas the certificate authority tests port 80 only.%0a%3c %0a%3c !!! Incorrect File Permissions%0a%3c %0a%3c Double check @@/var/www@@ and @@/var/www/acme@@ for correct file permissions:%0a%3c %0a---%0a> You should a response similar to the one below:%0a> %0a266,268c244,251%0a%3c $ ls -ld /var/www /var/www/acme%0a%3c drwxr-xr-x 10 root daemon 512 Oct 5 07:47 /var/www%0a%3c drwxr-xr-x 2 root daemon 512 Oct 5 07:47 /var/www/acme%0a---%0a> HTTP/1.0 302 Found%0a> Date: Tue, 23 Feb 2021 14:01:28 GMT%0a> OpenBSD httpd%0a> Connection: close%0a> Content-Type: text/html%0a> Content-Length: 486%0a> Location: https://example.com/index.html%0a> ...%0a269a253,283%0a> %0a> If you do not get this response, double check your openhttpd configuration.%0a> %0a> '''Note''': Using the telnet command above is more reliable than visiting the URL in a web browser. By default, httpd.conf (and most web browsers) will forward all requests for port 80 to port 443. As a result, your web browser will see what is listening on port 443, but the certificate authority will test port 80 only.%0a> %0a> %0a> !!! Incorrect File Permissions%0a> %0a> Double check the file permissions for /var/www and /var/www/acme:%0a> %0a> [@%0a> $ ls -ld /var/www /var/www/acme%0a> drwxr-xr-x 10 root daemon 512 Oct 5 07:47 /var/www%0a> drwxr-xr-x 2 root daemon 512 Oct 5 07:47 /var/www/acme%0a> @]%0a> %0a> !! Automation%0a> %0a> Let's Encrypt TLS certs expire after 90 days, while Buypass certs expire after 180. For both, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/edit|crontab]].%0a> %0a> [@%0a> $ doas crontab -e%0a> @]%0a> %0a> Add this line at the bottom:%0a> %0a> [@%0a> ~ ~ * * * acme-client example.com >> /var/log/acme-client.log 2>&1%0a> @]%0a> %0a> This cronjob will check the certificate once each day, at a random time of day, to see if it needs to be renewed. If it does, it will renew the cert.%0a
16 aa513bf8 2023-01-22 jrmu host:1655193716=38.87.162.154
17 aa513bf8 2023-01-22 jrmu author:1655192828=jrmu
18 aa513bf8 2023-01-22 jrmu diff:1655192828:1655192572:=212a213,222%0a> The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on.%0a> %0a> '''Note''': You '''cannot''' request a domain you don't own! The domain must point to an IP you own.%0a> %0a> There are a few possible mistakes:%0a> %0a> # Your web server is listening only one IPv4 but your DNS record includes IPv6; or vice versa.%0a> # You have the wrong IP addresses.%0a> # DNS records are missing.%0a> %0a219,225c229%0a%3c You will either need to speak with your DNS provider or troubleshoot [[nsd/troubleshoot|nsd]]. If DNS records are missing or incorrect, fix these first.%0a%3c %0a%3c The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on. If they do not match, you must fix this.%0a%3c %0a%3c '''Note''': You '''cannot''' request a domain you don't own! The domain must point to an IP you own.%0a%3c %0a%3c Lastly, if your DNS record includes an IPv6 address, make sure your web server is listening on IPv6. If the DNS record contains an IPv4 address, make sure your web server is listening on IPv4.%0a---%0a> You will either need to speak with your DNS provider or you will need to troubleshoot [[nsd/troubleshoot|nsd]].%0a
19 aa513bf8 2023-01-22 jrmu host:1655192828=38.87.162.154
20 aa513bf8 2023-01-22 jrmu author:1655192572=jrmu
21 aa513bf8 2023-01-22 jrmu diff:1655192572:1655191866:=125,136c125,131%0a%3c The public key goes inside the folder @@/etc/ssl@@ and the private key goes inside @@/etc/ssl/private@@.%0a%3c %0a%3c The line @@sign with letsencrypt@@ line tells Acme-client which Certificate Authority (which you defined in the Authority Blocks) to use.%0a%3c %0a%3c For testing purposes, you may want to change it to @@letsencrypt-staging@@. You can also consider using @@buypass@@ or @@buypass-test@@.%0a%3c %0a%3c '''Note''': staging or testing certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, change this line back to an official authority (such as @@sign with letsencrypt@@).%0a%3c %0a%3c !! Requesting Certificates%0a%3c %0a%3c After you have finished configuring the conf file, we can request certificates:%0a%3c %0a---%0a> Replace @@example.com@@ with your real domain. The public key goes inside the folder @@/etc/ssl@@ and the private key goes inside @@/etc/ssl/private@@.%0a> %0a> %0a> sign with: %0a> %0a> this line tells Acme-client which CA (that you defined in the Authority Blocks) to use.%0a> %0a138c133%0a%3c $ doas acme-client -Fv example.com%0a---%0a> sign with letsencrypt%0a141,142c136,143%0a%3c If there are no errors, you should see something similar to the following output:%0a%3c %0a---%0a> would cause it to use the CA @@ letsencrypt @@. For testing purposes, change it to @@ letsencrypt-staging @@. If you want to use @@ buypass @@ or it's testing CA @@ buypass-test @@, then change it accordingly.%0a> %0a> '''Note''': staging or testing certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, change this line back to an official authority (@@sign with letsencrypt@@).%0a> %0a> !! Requesting Certificates%0a> %0a> After you have finished configuring the conf file, we can request certificates:%0a> %0a144a146,153%0a> @]%0a> %0a> replace @@ example.com @@ with your domain.%0a> %0a> If there are no errors, you should see something similar to the following output:%0a> %0a> [@%0a> $ doas acme-client -Fv example.com%0a163,166c172,175%0a%3c The last line says that the public certificate was generated. If you see that, it's a success!%0a%3c %0a%3c You now have two certificates, the public key inside @@/etc/ssl/example.com.crt@@, and the private key inside @@/etc/ssl/private/example.com.key@@:%0a%3c %0a---%0a> Note the last line: it says that the public certificate was generated. If you see that, it's a success!%0a> %0a> You now have two certificates, the public key inside @@/etc/ssl/example.com.crt@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to):%0a> %0a169,170c178,179%0a%3c -r--r--r-- 1 root wheel 4797 Feb 25 02:11 /etc/ssl/example.com.crt%0a%3c -r-------- 1 root wheel 3272 Feb 25 02:10 /etc/ssl/private/example.com.key%0a---%0a> -r--r--r-- 1 root wheel 4797 Feb 25 02:11 /etc/ssl/jrmu.coconut.ircnow.org.crt%0a> -r-------- 1 root wheel 3272 Feb 25 02:10 /etc/ssl/private/jrmu.coconut.ircnow.org.key%0a185,186c194,197%0a%3c Here, @@new.example.com@@ was a new alternative name you added. The solution is to move your old public cert and private key to a new location (to back it up). Then, request the cert again.%0a%3c %0a---%0a> Here, @@new.example.com@@ was a new alternative name I added. The solution is to move your old public cert and private key to a new location (rather than deleting it, back it up!)%0a> %0a> Example (using example.com):%0a> %0a197a209%0a> %0a217c229%0a%3c There are a few possible mistakes:%0a---%0a> There are a few possible mistakes:%0a
22 aa513bf8 2023-01-22 jrmu host:1655192572=38.87.162.154
23 aa513bf8 2023-01-22 jrmu author:1655191866=jrmu
24 aa513bf8 2023-01-22 jrmu diff:1655191866:1655191536:=98,105c98,105%0a%3c First, replace every appearance of @@example.com@@ with your own domain.%0a%3c %0a%3c Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@example.com@@ and the alternative names @@www.example.com@@ and @@mail.example.com@@. You can safely skip this by commenting out this line (see warning below)%0a%3c %0a%3c If you use too many alternative names, an acme-client certificate request has a higher chance of failure. So, we recommend keeping the number of alternative names to under 5.%0a%3c %0a%3c '''Warning''': Having the @@alternative names@@ directive with nothing inside will cause errors. For example, the below will cause errors:%0a%3c %0a---%0a> domain: This would configure acme-client for the domain @@ example.com @@. Replace every appearance of @@ example.com @@ with your own domain, which might look like @@ username.fruit.ircnow.org @@.%0a> %0a> alternative names: Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@ example.ircnow.org @@ and the alternative names @@ fruit.ircnow.org @@ and @@ vegetable.ircnow.org @@. You can safely skip this by commenting out this line (see warning below)%0a> %0a> If you use too many alternative names, an acme-client certificate request has a higher chance of failure. So, I recommend keeping the number of alternative names to under 5.%0a> %0a> '''Warning''': Having the @@alternative names@@ directive with nothing inside will cause errors. The below will cause errors:%0a> %0a116,118c116,121%0a%3c '''Note''': If you add an alternative name to the conf file, but the cert already exists, you must remove the old public cert first before requesting a new one. Otherwise, you will get @@unknown SAN error@@ -- acme-client will complain there is an unknown '''Subject Alternative Name'''.%0a%3c %0a%3c Next, the @@domain key@@ and @@domain full chain certificate@@ tell acme-client where to put the private key and certificate:%0a---%0a> %0a> '''Note''': If you add an alternative name to the conf file, but the cert already exists, you must remove the old public cert first before requesting a new one. Otherwise, you will get @@unknown SAN error@@ -- acme-client will complain there is an unknown Subject Alternative Name.%0a> %0a> domain key, domain full chain certificate:%0a> %0a> The @@domain key@@ and @@domain full chain certificate@@ tell acme-client where to put the private key and certificate:%0a
25 aa513bf8 2023-01-22 jrmu host:1655191866=38.87.162.154
26 aa513bf8 2023-01-22 jrmu author:1655191536=jrmu
27 aa513bf8 2023-01-22 jrmu diff:1655191536:1649038510:=42c42%0a%3c Although we are using Let's Encrypt for this tutorial, it is important to note that having the majority of servers depend upon a single provider is dangerous. For this reason, it would be beneficial to someday have the community run its own Certificate Authority to avoid censorship of domains or other security issues.%0a---%0a> Although we are using Let's Encrypt for this tutorial, it is important to note that Let's Encrypt currently has a monopoly on free SSL certs. For this reason, IRCNow wants to run its own Certificate Authority in case Let's Encrypt should try to censor our domains.%0a
28 aa513bf8 2023-01-22 jrmu host:1655191536=38.87.162.154
29 aa513bf8 2023-01-22 jrmu author:1649038510=jrmu
30 aa513bf8 2023-01-22 jrmu diff:1649038510:1644404186:=299c299%0a%3c ~ ~ * * * acme-client example.com >> /var/log/acme-client.log 2>&1%0a---%0a> ~ ~ * * * acme-client example.com >> /var/log/acme-client.log 2>&1 && rcctl reload httpd%0a302c302%0a%3c This cronjob will check the certificate once each day, at a random time of day, to see if it needs to be renewed. If it does, it will renew the cert.%0a---%0a> This cronjob will check the certificate once each day, at a random time of day, to see if it needs to be renewed. If it does, it will renew the cert, then reload openhttpd to use it.%0a
31 aa513bf8 2023-01-22 jrmu host:1649038510=38.87.162.154
32 aa513bf8 2023-01-22 jrmu author:1644404186=SummerSonw
33 aa513bf8 2023-01-22 jrmu csum:1644404186=https://acme-staging-v02.api.letsencrypt.org/directory
34 aa513bf8 2023-01-22 jrmu diff:1644404186:1644404177:=
35 aa513bf8 2023-01-22 jrmu host:1644404186=203.77.49.232
36 aa513bf8 2023-01-22 jrmu author:1644404177=SummerSonw
37 aa513bf8 2023-01-22 jrmu csum:1644404177=https://acme-staging-v02.api.letsencrypt.org/directory
38 aa513bf8 2023-01-22 jrmu diff:1644404177:1644404155:=
39 aa513bf8 2023-01-22 jrmu host:1644404177=203.77.49.232
40 aa513bf8 2023-01-22 jrmu author:1644404155=SummerSonw
41 aa513bf8 2023-01-22 jrmu csum:1644404155=https://acme-staging-v02.api.letsencrypt.org/directory
42 aa513bf8 2023-01-22 jrmu diff:1644404155:1643583464:=46c46%0a%3c api url "https://acme-staging-v02.api.letsencrypt.org/directory"%0a---%0a> api url "https://acme-staging.api.letsencrypt.org/directory"%0a
43 aa513bf8 2023-01-22 jrmu host:1644404155=203.77.49.232
44 aa513bf8 2023-01-22 jrmu author:1643583464=jrmu
45 aa513bf8 2023-01-22 jrmu diff:1643583464:1643202311:=299c299%0a%3c ~ ~ * * * acme-client example.com >> /var/log/acme-client.log 2>&1 && rcctl reload httpd%0a---%0a> ~ ~ * * * acme-client example.com && rcctl reload httpd%0a
46 aa513bf8 2023-01-22 jrmu host:1643583464=38.87.162.8
47 aa513bf8 2023-01-22 jrmu author:1643202311=Naglfar
48 aa513bf8 2023-01-22 jrmu csum:1643202311=Update crontab reference
49 aa513bf8 2023-01-22 jrmu diff:1643202311:1642281315:=290c290%0a%3c Let's Encrypt TLS certs expire after 90 days, while Buypass certs expire after 180. For both, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/edit|crontab]].%0a---%0a> Let's Encrypt TLS certs expire after 90 days, while Buypass certs expire after 180. For both, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/configure|crontab]].%0a
50 aa513bf8 2023-01-22 jrmu host:1643202311=92.191.225.58
51 aa513bf8 2023-01-22 jrmu author:1642281315=jan6
52 aa513bf8 2023-01-22 jrmu csum:1642281315=fix renewal crontab to run randomly once a day, not once an hour
53 aa513bf8 2023-01-22 jrmu diff:1642281315:1636907615:minor=299c299%0a%3c ~ ~ * * * acme-client example.com && rcctl reload httpd%0a---%0a> ~ * * * * acme-client example.com && rcctl reload httpd%0a
54 aa513bf8 2023-01-22 jrmu host:1642281315=2a01:4f9:c010:291f::1
55 aa513bf8 2023-01-22 jrmu author:1636907615=theguest
56 aa513bf8 2023-01-22 jrmu diff:1636907615:1635981333:minor=9c9%0a%3c SSL certificates are obtained from CAs (Certificate Authorities). Currently, the only free CAs are [[https://letsencrypt.org/getting-started/ | Lets Encrypt]], [[https://www.buypass.com/ssl/products/acme | Buypass]] and [[https://zerossl.com/ | ZeroSSL]]. You can request an SSL cert for your web domain using an Automatic Certificate Management Environment (ACME) client such as OpenBSD's Acme-client, which we will configure in this article.%0a---%0a> SSL certificates are obtained from CA's (Certificate Authorities). Currently, the only free CA is Lets Encrypt. You can request an SSL cert for your web domain using an Automatic Certificate Management Environment (ACME) client such as OpenBSD's Acme-client, which we will configure in this article.%0a
57 aa513bf8 2023-01-22 jrmu host:1636907615=38.87.162.129
58 aa513bf8 2023-01-22 jrmu author:1635981333=jrmu
59 aa513bf8 2023-01-22 jrmu diff:1635981333:1635936085:=93c93%0a%3c domain full chain certificate "/etc/ssl/example.com.crt"%0a---%0a> domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a125c125%0a%3c domain full chain certificate "/etc/ssl/example.com.crt"%0a---%0a> domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a172c172%0a%3c acme-client: /etc/ssl/example.com.crt: created%0a---%0a> acme-client: /etc/ssl/example.com.fullchain.pem: created%0a177,178c177,178%0a%3c You now have two certificates, the public key inside @@/etc/ssl/example.com.crt@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to):%0a%3c %0a---%0a> You now have two certificates, the public key inside @@/etc/ssl/example.com.fullchain.pem@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to):%0a> %0a180,181c180,181%0a%3c $ doas ls -l /etc/ssl/example.com.crt /etc/ssl/private/example.com.key%0a%3c -r--r--r-- 1 root wheel 4797 Feb 25 02:11 /etc/ssl/jrmu.coconut.ircnow.org.crt%0a---%0a> $ doas ls -l /etc/ssl/example.com.fullchain.pem /etc/ssl/private/example.com.key%0a> -r--r--r-- 1 root wheel 4797 Feb 25 02:11 /etc/ssl/jrmu.coconut.ircnow.org.fullchain.pem%0a194c194%0a%3c acme-client: /etc/ssl/example.com.crt: domain not listed: new.example.com%0a---%0a> acme-client: /etc/ssl/example.com.fullchain.pem: domain not listed: new.example.com%0a202c202%0a%3c $ doas mv /etc/ssl/example.com.crt /etc/ssl/example.com.crt.bak%0a---%0a> $ doas mv /etc/ssl/example.com.fullchain.pem /etc/ssl/example.com.fullchain.pem.bak%0a
60 aa513bf8 2023-01-22 jrmu host:1635981333=38.87.162.47
61 aa513bf8 2023-01-22 jrmu author:1635936085=jrmu
62 aa513bf8 2023-01-22 jrmu diff:1635936085:1629257098:=11,15c11,15%0a%3c !!! Before You Begin %0a%3c %0a%3c You will first need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need properly functioning [[dns/overview|DNS records]] for your hostname (@@username.example.com@@). If you are using a training vps, it is likely that DNS records for your hostname have already been set up for you.%0a%3c %0a%3c You can and should test the two configurations using [[host/usage|host]] and [[netcat/http|netcat]].%0a---%0a> !!! Prerequisites %0a> %0a> Openhttpd:%0a> %0a> Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning [[dns/overview|DNS records]] for your hostname, which might look like @@username.fruit.ircnow.org@@. If you are using a training vps, it is likely that your DNS record (your domain) is already set up for now, and will have the form @@username.host.ircnow.org@@%0a
63 aa513bf8 2023-01-22 jrmu host:1635936085=38.87.162.47
64 aa513bf8 2023-01-22 jrmu author:1629257098=craziness
65 aa513bf8 2023-01-22 jrmu csum:1629257098=fixed a misspelling
66 aa513bf8 2023-01-22 jrmu diff:1629257098:1626873311:=128c128%0a%3c Replace @@example.com@@ with your real domain. The public key goes inside the folder @@/etc/ssl@@ and the private key goes inside @@/etc/ssl/private@@.%0a---%0a> Replace @@example.com@@ with your real domain. The public key goes inside the forlder @@/etc/ssl@@ and the private key goes inside @@/etc/ssl/private@@.%0a
67 aa513bf8 2023-01-22 jrmu host:1629257098=2601:546:8200:3710::66f4
68 aa513bf8 2023-01-22 jrmu author:1626873311=mistera
69 aa513bf8 2023-01-22 jrmu diff:1626873311:1626873281:=141c141%0a%3c '''Note''': staging or testing certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, change this line back to an official authority (@@sign with letsencrypt@@).%0a---%0a> '''Note''': staging or testing certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, change this line back to an official authority.%0a
70 aa513bf8 2023-01-22 jrmu host:1626873311=204.111.39.57
71 aa513bf8 2023-01-22 jrmu author:1626873281=mistera
72 aa513bf8 2023-01-22 jrmu diff:1626873281:1626871882:=
73 aa513bf8 2023-01-22 jrmu host:1626873281=204.111.39.57
74 aa513bf8 2023-01-22 jrmu author:1626871882=mistera
75 aa513bf8 2023-01-22 jrmu diff:1626871882:1626871865:=55c55%0a%3c [@%0a---%0a> @@%0a67c67%0a%3c @]%0a---%0a> @@%0a
76 aa513bf8 2023-01-22 jrmu host:1626871882=204.111.39.57
77 aa513bf8 2023-01-22 jrmu author:1626871865=mistera
78 aa513bf8 2023-01-22 jrmu diff:1626871865:1626871816:=55c55%0a%3c @@%0a---%0a> [@%0a67c67%0a%3c @@%0a---%0a> @]%0a
79 aa513bf8 2023-01-22 jrmu host:1626871865=204.111.39.57
80 aa513bf8 2023-01-22 jrmu author:1626871816=mistera
81 aa513bf8 2023-01-22 jrmu diff:1626871816:1626871739:=53c53%0a%3c To both of these blocks, we will want to add our contact email, so we add [@contact "mailto:me@example.com" @] inside both blocks. (make sure to have the @@mailto:@@):%0a---%0a> To both of these blocks, we will want to add our contact email, so we add @@contact mailto:me@example.com @@ inside both blocks:%0a
82 aa513bf8 2023-01-22 jrmu host:1626871816=204.111.39.57
83 aa513bf8 2023-01-22 jrmu author:1626871739=mistera
84 aa513bf8 2023-01-22 jrmu diff:1626871739:1626871579:=53c53%0a%3c To both of these blocks, we will want to add our contact email, so we add @@contact mailto:me@example.com @@ inside both blocks:%0a---%0a> To both of these blocks, we will want to add our contact email, so we add @@contact "mailto:me@example.com"@@ inside both blocks:%0a
85 aa513bf8 2023-01-22 jrmu host:1626871739=204.111.39.57
86 aa513bf8 2023-01-22 jrmu author:1626871579=mistera
87 aa513bf8 2023-01-22 jrmu diff:1626871579:1626788685:=27c27%0a%3c We'll open up [@ /etc/acme-client.conf @] and analyze the meaning of each block:%0a---%0a> We'll open up /etc/acme-client.conf and analyze the meaning of each block:%0a
88 aa513bf8 2023-01-22 jrmu host:1626871579=204.111.39.57
89 aa513bf8 2023-01-22 jrmu author:1626788685=mistera
90 aa513bf8 2023-01-22 jrmu diff:1626788685:1626786887:=5c5%0a%3c !! Overview%0a---%0a> !! Theory%0a
91 aa513bf8 2023-01-22 jrmu host:1626788685=204.111.39.57
92 aa513bf8 2023-01-22 jrmu author:1626786887=mistera
93 aa513bf8 2023-01-22 jrmu diff:1626786887:1619180493:=5,16c5,8%0a%3c !! Theory%0a%3c %0a%3c TLS (Transport Layer Security) aka SSL (Secure Sockets Layer) is the encryption security measure that enables browsers to recognize a website as "secure". In modern browsers the SSL information can be accessed by clicking the padlock icon in the address bar. %0a%3c %0a%3c SSL certificates are obtained from CA's (Certificate Authorities). Currently, the only free CA is Lets Encrypt. You can request an SSL cert for your web domain using an Automatic Certificate Management Environment (ACME) client such as OpenBSD's Acme-client, which we will configure in this article.%0a%3c %0a%3c !!! Prerequisites %0a%3c %0a%3c Openhttpd:%0a%3c %0a%3c Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning [[dns/overview|DNS records]] for your hostname, which might look like @@username.fruit.ircnow.org@@. If you are using a training vps, it is likely that your DNS record (your domain) is already set up for now, and will have the form @@username.host.ircnow.org@@%0a%3c %0a---%0a> !! Setting up OpenHTTPd%0a> %0a> Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning [[dns/overview|DNS records]] for your hostname, which might look like @@username.fruit.ircnow.org@@.%0a> %0a29,30d20%0a%3c !!! Authority blocks%0a%3c %0a40,41c30,31%0a%3c '''Note''': Let's Encrypt [[https://letsencrypt.org/docs/rate-limits/|rate-limits]] the number of SSL certs you can request. If you encounter an error and are unable to request an SSL cert, please fix all errors before requesting again. If you request too many certs in a short time, your domain will get blacklisted for a few hours or days. To avoid issues, use letsencrypt-staging first and make sure you get success with that before using letsencrypt.%0a%3c %0a---%0a> '''Note''': Let's Encrypt [[https://letsencrypt.org/docs/rate-limits/|rate-limits]] the number of SSL certs you can request. If you encounter an error and are unable to request an SSL cert, please fix all errors before requesting again. If you request too many certs in a short time, your domain will get blacklisted for a few hours or days.%0a> %0a87,88d76%0a%3c !!! Domain Block%0a%3c %0a98,101c86,89%0a%3c domain: This would configure acme-client for the domain @@ example.com @@. Replace every appearance of @@ example.com @@ with your own domain, which might look like @@ username.fruit.ircnow.org @@.%0a%3c %0a%3c alternative names: Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@ example.ircnow.org @@ and the alternative names @@ fruit.ircnow.org @@ and @@ vegetable.ircnow.org @@. You can safely skip this by commenting out this line (see warning below)%0a%3c %0a---%0a> This configures acme-client for the domain example.com. You'll want to replace every appearance of @@example.com@@ with your own domain, which might look like @@username.fruit.ircnow.org@@.%0a> %0a> Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@example.ircnow.org@@ and the alternative names @@fruit.ircnow.org@@ and @@vegetable.ircnow.org@@.%0a> %0a119,120d106%0a%3c domain key, domain full chain certificate:%0a%3c %0a128,134c114,117%0a%3c Replace @@example.com@@ with your real domain. The public key goes inside the forlder @@/etc/ssl@@ and the private key goes inside @@/etc/ssl/private@@.%0a%3c %0a%3c %0a%3c sign with: %0a%3c %0a%3c this line tells Acme-client which CA (that you defined in the Authority Blocks) to use.%0a%3c %0a---%0a> You will want to replace @@example.com@@ with your real domain. The public key should go inside @@/etc/ssl@@ and the private key should go inside @@/etc/ssl/private@@.%0a> %0a> If you want to sign with buypass, test a staging certificate (to avoid using up your rate-limit), or switch to another authority, then edit this line:%0a> %0a139,142c122,128%0a%3c would cause it to use the CA @@ letsencrypt @@. For testing purposes, change it to @@ letsencrypt-staging @@. If you want to use @@ buypass @@ or it's testing CA @@ buypass-test @@, then change it accordingly.%0a%3c %0a%3c '''Note''': staging or testing certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, change this line back to an official authority.%0a%3c %0a---%0a> Change it to match one of your defined authorities. For example:%0a> %0a> # To test with letsencrypt-staging, replace it with @@sign with letsencrypt-staging@@.%0a> # To sign with buypass, replace it with @@sign with buypass@@.%0a> %0a> '''Note''': staging certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, you will want to get a properly signed one.%0a> %0a151,152d136%0a%3c replace @@ example.com @@ with your domain.%0a%3c %0a175,176c159,160%0a%3c Note the last line: it says that the public certificate was generated. If you see that, it's a success!%0a%3c %0a---%0a> Pay attention to the last line: it says that the public certificate was generated. If you see that, it's a success!%0a> %0a189,192c173,176%0a%3c !!! Domain Not Listed%0a%3c %0a%3c If you add a new alternative name inside your domain block in [[https://man.openbsd.org/acme-client.conf|/etc/acme-client.conf]], you will see this error:%0a%3c %0a---%0a> !!! Missing Domain Records%0a> %0a> It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a> %0a194c178%0a%3c acme-client: /etc/ssl/example.com.fullchain.pem: domain not listed: new.example.com%0a---%0a> $ host example.com%0a197,200c181,182%0a%3c Here, @@new.example.com@@ was a new alternative name I added. The solution is to move your old public cert and private key to a new location (rather than deleting it, back it up!)%0a%3c %0a%3c Example (using example.com):%0a%3c %0a---%0a> You should see one or two records like the following:%0a> %0a202,203c184,185%0a%3c $ doas mv /etc/ssl/example.com.fullchain.pem /etc/ssl/example.com.fullchain.pem.bak%0a%3c $ doas mv /etc/ssl/private/example.com.key /etc/ssl/private/example.com.key.bak%0a---%0a> example.com has address 93.184.216.34%0a> example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a206,207c188,199%0a%3c Then request the cert again:%0a%3c %0a---%0a> The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on.%0a> %0a> '''Note''': You '''cannot''' request a domain you don't own! The domain must point to an IP you own.%0a> %0a> There are a few possible mistakes:%0a> %0a> # Your web server is listening only one IPv4 but your DNS record includes IPv6; or vice versa.%0a> # You have the wrong IP addresses.%0a> # DNS records are missing.%0a> %0a> If you have missing records, you will see this response:%0a> %0a209c201%0a%3c $ doas acme-client -Fv example.com%0a---%0a> Host example.com not found: 3(NXDOMAIN)%0a212,216c204,211%0a%3c %0a%3c !!! Missing Domain Records%0a%3c %0a%3c It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a%3c %0a---%0a> You will either need to speak with your DNS provider or you will need to troubleshoot [[nsd/troubleshoot|nsd]].%0a> %0a> !!! OpenHTTPd Misconfigured%0a> %0a> acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. If [[openhttpd/configure|openhttpd]] is not configured and running properly, acme-client won't work.%0a> %0a> To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain):%0a> %0a218c213,215%0a%3c $ host example.com%0a---%0a> $ telnet example.com 80%0a> GET /index.html HTTP/1.1%0a> Host: example.com%0a221,222c218,219%0a%3c You should see one or two records like the following:%0a%3c %0a---%0a> You should a response similar to the one below:%0a> %0a224,225c221,228%0a%3c example.com has address 93.184.216.34%0a%3c example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a---%0a> HTTP/1.0 302 Found%0a> Date: Tue, 23 Feb 2021 14:01:28 GMT%0a> OpenBSD httpd%0a> Connection: close%0a> Content-Type: text/html%0a> Content-Length: 486%0a> Location: https://example.com/index.html%0a> ...%0a228,239c231,238%0a%3c The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on.%0a%3c %0a%3c '''Note''': You '''cannot''' request a domain you don't own! The domain must point to an IP you own.%0a%3c %0a%3c There are a few possible mistakes:%0a%3c %0a%3c # Your web server is listening only one IPv4 but your DNS record includes IPv6; or vice versa.%0a%3c # You have the wrong IP addresses.%0a%3c # DNS records are missing.%0a%3c %0a%3c If you have missing records, you will see this response:%0a%3c %0a---%0a> If you do not get this response, double check your openhttpd configuration.%0a> %0a> '''Note''': Using the telnet command above is more reliable than visiting the URL in a web browser. By default, httpd.conf (and most web browsers) will forward all requests for port 80 to port 443. As a result, your web browser will see what is listening on port 443, but the certificate authority will test port 80 only.%0a> %0a> !!! Domain Not Listed%0a> %0a> If you add a new alternative name inside your domain block in [[https://man.openbsd.org/acme-client.conf|/etc/acme-client.conf]], you will see this error:%0a> %0a241c240%0a%3c Host example.com not found: 3(NXDOMAIN)%0a---%0a> acme-client: /etc/ssl/example.com.fullchain.pem: domain not listed: new.example.com%0a244,253c243,244%0a%3c You will either need to speak with your DNS provider or you will need to troubleshoot [[nsd/troubleshoot|nsd]].%0a%3c %0a%3c !!! OpenHTTPd Misconfigured%0a%3c %0a%3c If [[openhttpd/configure|openhttpd]] is not configured and running properly, acme-client won't work.%0a%3c %0a%3c (acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. )%0a%3c %0a%3c To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain) from another computer:%0a%3c %0a---%0a> Here, @@new.example.com@@ was a new alternative name I added. The solution is to move your old public cert and private key to a new location, then request the cert again:%0a> %0a255,257c246,247%0a%3c $ telnet example.com 80%0a%3c GET /index.html HTTP/1.1%0a%3c Host: example.com%0a---%0a> $ doas mv /etc/ssl/example.com.fullchain.pem /etc/ssl/example.com.fullchain.pem.bak%0a> $ doas mv /etc/ssl/private/example.com.key /etc/ssl/private/example.com.key.bak%0a260,261c250,251%0a%3c You should a response similar to the one below:%0a%3c %0a---%0a> Again, you must replace @@example.com@@ with your actual domain. Then:%0a> %0a263,270c253%0a%3c HTTP/1.0 302 Found%0a%3c Date: Tue, 23 Feb 2021 14:01:28 GMT%0a%3c OpenBSD httpd%0a%3c Connection: close%0a%3c Content-Type: text/html%0a%3c Content-Length: 486%0a%3c Location: https://example.com/index.html%0a%3c ...%0a---%0a> $ doas acme-client -Fv example.com%0a272,276d254%0a%3c %0a%3c If you do not get this response, double check your openhttpd configuration.%0a%3c %0a%3c '''Note''': Using the telnet command above is more reliable than visiting the URL in a web browser. By default, httpd.conf (and most web browsers) will forward all requests for port 80 to port 443. As a result, your web browser will see what is listening on port 443, but the certificate authority will test port 80 only.%0a%3c %0a
94 aa513bf8 2023-01-22 jrmu host:1626786887=204.111.39.57
95 aa513bf8 2023-01-22 jrmu author:1619180493=jrmu
96 aa513bf8 2023-01-22 jrmu diff:1619180493:1619176983:=105c105,106%0a%3c '''Note''': If you add an alternative name to the conf file, but the cert already exists, you must remove the old public cert first before requesting a new one. Otherwise, you will get @@unknown SAN error@@ -- acme-client will complain there is an unknown Subject Alternative Name.%0a---%0a> '+'''Please note that if you add an alternative name while there is already an existing cert, that you have to remove the old certs and then use continue.'''+'%0a> %0a
97 aa513bf8 2023-01-22 jrmu host:1619180493=198.251.81.119
98 aa513bf8 2023-01-22 jrmu author:1619176983=miniontoby
99 aa513bf8 2023-01-22 jrmu csum:1619176983=cert
100 aa513bf8 2023-01-22 jrmu diff:1619176983:1619176919:=104,107d103%0a%3c %0a%3c '+'''Please note that if you add an alternative name while there is already an existing cert, that you have to remove the old certs and then use continue.'''+'%0a%3c %0a%3c %0a281a278,282%0a> %0a> %0a> '+'''Please note that if you add an alternative name, that you have to remove the old certs and then use acme-client.'''+'%0a> %0a> %0a
101 aa513bf8 2023-01-22 jrmu host:1619176983=77.168.188.164
102 aa513bf8 2023-01-22 jrmu author:1619176919=miniontoby
103 aa513bf8 2023-01-22 jrmu diff:1619176919:1614320419:=278,282d277%0a%3c %0a%3c %0a%3c '+'''Please note that if you add an alternative name, that you have to remove the old certs and then use acme-client.'''+'%0a%3c %0a%3c %0a
104 aa513bf8 2023-01-22 jrmu host:1619176919=77.168.188.164
105 aa513bf8 2023-01-22 jrmu author:1614320419=jrmu
106 aa513bf8 2023-01-22 jrmu diff:1614320419:1614254423:=265c265%0a%3c Let's Encrypt TLS certs expire after 90 days, while Buypass certs expire after 180. For both, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/configure|crontab]].%0a---%0a> ACME TLS certs expire after 90 days. So, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/configure|crontab]].%0a
107 aa513bf8 2023-01-22 jrmu host:1614320419=198.251.81.119
108 aa513bf8 2023-01-22 jrmu author:1614254423=jrmu
109 aa513bf8 2023-01-22 jrmu diff:1614254423:1614254344:=277c277%0a%3c This cronjob will check the certificate once each day, at a random time of day, to see if it needs to be renewed. If it does, it will renew the cert, then reload openhttpd to use it.%0a---%0a> This cronjob will check the certificate once a day to see if it needs to be renewed. If it does, it will renew the cert, then reload openhttpd to use it.%0a
110 aa513bf8 2023-01-22 jrmu host:1614254423=198.251.81.119
111 aa513bf8 2023-01-22 jrmu author:1614254344=jrmu
112 aa513bf8 2023-01-22 jrmu diff:1614254344:1614248928:=262,277d261%0a%3c %0a%3c !! Automation%0a%3c %0a%3c ACME TLS certs expire after 90 days. So, you must remember to request the TLS cert or TLS will stop working. To avoid forgetting, we can automate the request process using [[crontab/configure|crontab]].%0a%3c %0a%3c [@%0a%3c $ doas crontab -e%0a%3c @]%0a%3c %0a%3c Add this line at the bottom:%0a%3c %0a%3c [@%0a%3c ~ * * * * acme-client example.com && rcctl reload httpd%0a%3c @]%0a%3c %0a%3c This cronjob will check the certificate once a day to see if it needs to be renewed. If it does, it will renew the cert, then reload openhttpd to use it.%0a
113 aa513bf8 2023-01-22 jrmu host:1614254344=198.251.81.119
114 aa513bf8 2023-01-22 jrmu author:1614248928=jrmu
115 aa513bf8 2023-01-22 jrmu diff:1614248928:1614248764:=265,268c265,267%0a%3c || border=1 width=100%25 class="sortable simpletable"%0a%3c || [[openhttpd/configure|Configure OpenHTTPd]] || Configure HTTPd ||%0a%3c || [[telnet/http|Telnet HTTP]] || Use Telnet to Troubleshoot HTTP ||%0a%3c || [[openssl/http|OpenSSL HTTP]] || Use OpenSSL to Troubleshoot HTTPS ||%0a---%0a> [[openhttpd/configure|Configure OpenHTTPd]]%0a> [[telnet/HTTP|Telnet HTTP]]%0a> [[openssl/HTTP|OpenSSL HTTP]]%0a
116 aa513bf8 2023-01-22 jrmu host:1614248928=198.251.81.119
117 aa513bf8 2023-01-22 jrmu author:1614248764=jrmu
118 aa513bf8 2023-01-22 jrmu diff:1614248764:1614248201:=247,252d246%0a%3c Again, you must replace @@example.com@@ with your actual domain. Then:%0a%3c %0a%3c [@%0a%3c $ doas acme-client -Fv example.com%0a%3c @]%0a%3c %0a261,267c255%0a%3c @]%0a%3c %0a%3c See Also:%0a%3c %0a%3c [[openhttpd/configure|Configure OpenHTTPd]]%0a%3c [[telnet/HTTP|Telnet HTTP]]%0a%3c [[openssl/HTTP|OpenSSL HTTP]]%0a---%0a> @]%0a\ No newline at end of file%0a
119 aa513bf8 2023-01-22 jrmu host:1614248764=198.251.81.119
120 aa513bf8 2023-01-22 jrmu author:1614248201=jrmu
121 aa513bf8 2023-01-22 jrmu diff:1614248201:1614247880:=231,245d230%0a%3c %0a%3c !!! Domain Not Listed%0a%3c %0a%3c If you add a new alternative name inside your domain block in [[https://man.openbsd.org/acme-client.conf|/etc/acme-client.conf]], you will see this error:%0a%3c %0a%3c [@%0a%3c acme-client: /etc/ssl/example.com.fullchain.pem: domain not listed: new.example.com%0a%3c @]%0a%3c %0a%3c Here, @@new.example.com@@ was a new alternative name I added. The solution is to move your old public cert and private key to a new location, then request the cert again:%0a%3c %0a%3c [@%0a%3c $ doas mv /etc/ssl/example.com.fullchain.pem /etc/ssl/example.com.fullchain.pem.bak%0a%3c $ doas mv /etc/ssl/private/example.com.key /etc/ssl/private/example.com.key.bak%0a%3c @]%0a
122 aa513bf8 2023-01-22 jrmu host:1614248201=198.251.81.119
123 aa513bf8 2023-01-22 jrmu author:1614247880=jrmu
124 aa513bf8 2023-01-22 jrmu diff:1614247880:1614247705:=185,190c185,186%0a%3c The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on.%0a%3c %0a%3c '''Note''': You '''cannot''' request a domain you don't own! The domain must point to an IP you own.%0a%3c %0a%3c There are a few possible mistakes:%0a%3c %0a---%0a> The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on. There are a few possible mistakes:%0a> %0a240c236,241%0a%3c @]%0a\ No newline at end of file%0a---%0a> @]%0a> %0a> !! Common errors%0a> %0a> # Do not request domains you don't own%0a> # If you change the domains, you need to move the cert and request again%0a\ No newline at end of file%0a
125 aa513bf8 2023-01-22 jrmu host:1614247880=198.251.81.119
126 aa513bf8 2023-01-22 jrmu author:1614247705=jrmu
127 aa513bf8 2023-01-22 jrmu diff:1614247705:1614247508:=
128 aa513bf8 2023-01-22 jrmu host:1614247705=198.251.81.119
129 aa513bf8 2023-01-22 jrmu author:1614247508=jrmu
130 aa513bf8 2023-01-22 jrmu diff:1614247508:1614247487:=
131 aa513bf8 2023-01-22 jrmu host:1614247508=198.251.81.119
132 aa513bf8 2023-01-22 jrmu author:1614247487=jrmu
133 aa513bf8 2023-01-22 jrmu diff:1614247487:1614245123:=134,135c134,135%0a%3c If there are no errors, you should see something similar to the following output:%0a%3c %0a---%0a> If all goes well, you should see something similar to the following output:%0a> %0a156,159c156%0a%3c Pay attention to the last line: it says that the public certificate was generated. If you see that, it's a success!%0a%3c %0a%3c You now have two certificates, the public key inside @@/etc/ssl/example.com.fullchain.pem@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to):%0a%3c %0a---%0a> %0a161,163c158%0a%3c $ doas ls -l /etc/ssl/example.com.fullchain.pem /etc/ssl/private/example.com.key%0a%3c -r--r--r-- 1 root wheel 4797 Feb 25 02:11 /etc/ssl/jrmu.coconut.ircnow.org.fullchain.pem%0a%3c -r-------- 1 root wheel 3272 Feb 25 02:10 /etc/ssl/private/jrmu.coconut.ircnow.org.key%0a---%0a> acme-client: /etc/ssl/example.com.fullchain.pem: created%0a164a160,174%0a> %0a> %0a> [@%0a> $ doas ls -l /etc/ssl/private%0a> -r-------- 1 root wheel 3272 Mar 28 22:16 example.com.key%0a> @]%0a> # A PEM certificate under /etc/ssl e.g.%0a> [@%0a> $ ls -l /etc/ssl/*.pem%0a> -r--r--r-- 1 root wheel 3937 Mar 28 22:16 example.com.fullchain.pem%0a> @]%0a> %0a> It would have the following output of running acme-client, generating a certificate for example.com%0a> %0a> You should now have two certificates, the public key inside @@/etc/ssl/example.com.fullchain.pem@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to).%0a
134 aa513bf8 2023-01-22 jrmu host:1614247487=198.251.81.119
135 aa513bf8 2023-01-22 jrmu author:1614245123=jrmu
136 aa513bf8 2023-01-22 jrmu diff:1614245123:1614242993:=134,135c134,135%0a%3c If all goes well, you should see something similar to the following output:%0a%3c %0a---%0a> If all goes well, you should see the following line at the very bottom:%0a> %0a137,152d136%0a%3c $ doas acme-client -Fv example.com%0a%3c acme-client: /etc/acme/letsencrypt-privkey.pem: generated RSA account key%0a%3c acme-client: /etc/ssl/private/example.com.key: generated RSA domain key%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/directory: directories%0a%3c acme-client: acme-v02.api.letsencrypt.org: DNS: 172.65.32.248%0a%3c acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/11133258838%0a%3c acme-client: challenge, token: uWHZmqhx6NEpcv25LEvodMAeymB1guTFVtyktVzkJgs, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/11133258838/_UI3-A, status: 0%0a%3c acme-client: /var/www/acme/uWHZmqhx6NEpcv25LEvodMAeymB1guTFVtyktVzkJgs: created%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/11133258838/_UI3-A: challenge%0a%3c acme-client: order.status 0%0a%3c acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/11133258838%0a%3c acme-client: challenge, token: uWHZmqhx6NEpcv25LEvodMAeymB1guTFVtyktVzkJgs, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/11133258838/_UI3-A, status: 2%0a%3c acme-client: order.status 1%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/acme/finalize/113861127/8112730231: certificate%0a%3c acme-client: order.status 3%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/acme/cert/03f7fd846802cb0689c2bbd7b6f5e89eb66b: certificate%0a156c140,149%0a%3c %0a---%0a> You should now have two certificates, the public key inside @@/etc/ssl/example.com.fullchain.pem@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to).%0a> %0a> !! Troubleshooting%0a> %0a> If acme-client fails, there are several possible causes:%0a> %0a> !!! Missing Domain Records%0a> %0a> It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a> %0a158c151%0a%3c acme-client: /etc/ssl/example.com.fullchain.pem: created%0a---%0a> $ host example.com%0a161c154,155%0a%3c %0a---%0a> You should see one or two records like the following:%0a> %0a163,164c157,158%0a%3c $ doas ls -l /etc/ssl/private%0a%3c -r-------- 1 root wheel 3272 Mar 28 22:16 example.com.key%0a---%0a> example.com has address 93.184.216.34%0a> example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a166c160,168%0a%3c # A PEM certificate under /etc/ssl e.g.%0a---%0a> %0a> The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on. There are a few possible mistakes:%0a> %0a> # Your web server is listening only one IPv4 but your DNS record includes IPv6; or vice versa.%0a> # You have the wrong IP addresses.%0a> # DNS records are missing.%0a> %0a> If you have missing records, you will see this response:%0a> %0a168,169c170%0a%3c $ ls -l /etc/ssl/*.pem%0a%3c -r--r--r-- 1 root wheel 3937 Mar 28 22:16 example.com.fullchain.pem%0a---%0a> Host example.com not found: 3(NXDOMAIN)%0a172,183c173,180%0a%3c It would have the following output of running acme-client, generating a certificate for example.com%0a%3c %0a%3c You should now have two certificates, the public key inside @@/etc/ssl/example.com.fullchain.pem@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to).%0a%3c %0a%3c !! Troubleshooting%0a%3c %0a%3c If acme-client fails, there are several possible causes:%0a%3c %0a%3c !!! Missing Domain Records%0a%3c %0a%3c It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a%3c %0a---%0a> You will either need to speak with your DNS provider or you will need to troubleshoot [[nsd/troubleshoot|nsd]].%0a> %0a> !!! OpenHTTPd Misconfigured%0a> %0a> acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. If [[openhttpd/configure|openhttpd]] is not configured and running properly, acme-client won't work.%0a> %0a> To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain):%0a> %0a185c182,184%0a%3c $ host example.com%0a---%0a> $ telnet example.com 80%0a> GET /index.html HTTP/1.1%0a> Host: example.com%0a188,189c187,188%0a%3c You should see one or two records like the following:%0a%3c %0a---%0a> You should a response similar to the one below:%0a> %0a191,192c190,197%0a%3c example.com has address 93.184.216.34%0a%3c example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a---%0a> HTTP/1.0 302 Found%0a> Date: Tue, 23 Feb 2021 14:01:28 GMT%0a> OpenBSD httpd%0a> Connection: close%0a> Content-Type: text/html%0a> Content-Length: 486%0a> Location: https://example.com/index.html%0a> ...%0a195,202c200,205%0a%3c The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on. There are a few possible mistakes:%0a%3c %0a%3c # Your web server is listening only one IPv4 but your DNS record includes IPv6; or vice versa.%0a%3c # You have the wrong IP addresses.%0a%3c # DNS records are missing.%0a%3c %0a%3c If you have missing records, you will see this response:%0a%3c %0a---%0a> If you do not get this response, double check your openhttpd configuration.%0a> %0a> '''Note''': Using the telnet command above is more reliable than visiting the URL in a web browser. By default, httpd.conf (and most web browsers) will forward all requests to port 80 to port 443. As a result, your web browser will see what is listening on port 443, but the certificate authority will test port 80 only.%0a> %0a> # You have the proper permissions set on the folders in /var/www/. An example output would be,%0a> %0a204c207,218%0a%3c Host example.com not found: 3(NXDOMAIN)%0a---%0a> $ ls -l /var | grep www%0a> drwxr-xr-x 11 root daemon 512 Mar 28 05:28 www%0a> $ ls -l /var/www%0a> total 36%0a> drwxr-xr-x 2 root daemon 512 Mar 28 22:16 acme%0a> drwxr-xr-x 2 root daemon 512 Mar 14 06:12 bin%0a> drwx-----T 2 www daemon 512 Oct 12 12:34 cache%0a> drwxr-xr-x 2 root daemon 512 Mar 14 06:12 cgi-bin%0a> drwxr-xr-x 2 root daemon 512 Mar 14 06:03 conf%0a> drwxr-xr-x 3 root daemon 512 Oct 12 12:34 htdocs%0a> drwxr-xr-x 2 root daemon 512 Mar 29 00:00 logs%0a> drwxr-xr-x 2 root daemon 512 Oct 12 12:34 run%0a206,214c220,224%0a%3c %0a%3c You will either need to speak with your DNS provider or you will need to troubleshoot [[nsd/troubleshoot|nsd]].%0a%3c %0a%3c !!! OpenHTTPd Misconfigured%0a%3c %0a%3c acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. If [[openhttpd/configure|openhttpd]] is not configured and running properly, acme-client won't work.%0a%3c %0a%3c To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain):%0a%3c %0a---%0a> # Your firewall is not configured to block Let's Encrypt certification verification process. Typically it will initiate a few servers to connect to port 80 on your server.%0a> %0a> !! Successful outcomes%0a> A successful outcome would result in:%0a> # A ASCII text file, suffixed with .key with your hostname in /etc/ssl/private e.g.%0a216,218c226,227%0a%3c $ telnet example.com 80%0a%3c GET /index.html HTTP/1.1%0a%3c Host: example.com%0a---%0a> $ doas ls -l /etc/ssl/private%0a> -r-------- 1 root wheel 3272 Mar 28 22:16 example.com.key%0a220,222c229%0a%3c %0a%3c You should a response similar to the one below:%0a%3c %0a---%0a> # A PEM certificate under /etc/ssl e.g.%0a224,231c231,232%0a%3c HTTP/1.0 302 Found%0a%3c Date: Tue, 23 Feb 2021 14:01:28 GMT%0a%3c OpenBSD httpd%0a%3c Connection: close%0a%3c Content-Type: text/html%0a%3c Content-Length: 486%0a%3c Location: https://example.com/index.html%0a%3c ...%0a---%0a> $ ls -l /etc/ssl/*.pem%0a> -r--r--r-- 1 root wheel 3937 Mar 28 22:16 example.com.fullchain.pem%0a234,241c235,236%0a%3c If you do not get this response, double check your openhttpd configuration.%0a%3c %0a%3c '''Note''': Using the telnet command above is more reliable than visiting the URL in a web browser. By default, httpd.conf (and most web browsers) will forward all requests for port 80 to port 443. As a result, your web browser will see what is listening on port 443, but the certificate authority will test port 80 only.%0a%3c %0a%3c !!! Incorrect File Permissions%0a%3c %0a%3c Double check the file permissions for /var/www and /var/www/acme:%0a%3c %0a---%0a> It would have the following output of running acme-client, generating a certificate for example.com%0a> %0a243,245c238,263%0a%3c $ ls -ld /var/www /var/www/acme%0a%3c drwxr-xr-x 10 root daemon 512 Oct 5 07:47 /var/www%0a%3c drwxr-xr-x 2 root daemon 512 Oct 5 07:47 /var/www/acme%0a---%0a> acme-client: /etc/ssl/private/example.com.key: generated RSA domain key%0a> acme-client: /etc/acme/letsencrypt-privkey.pem: generated RSA account key%0a> acme-client: https://acme-v02.api.letsencrypt.org/directory: directories%0a> acme-client: acme-v02.api.letsencrypt.org: DNS: 172.65.32.248%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/3674632835%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: challenge, token: mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ, status: 0%0a> acme-client: /var/www/acme/mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL: created%0a> acme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ: challenge%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: order.status 0%0a> acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/3674632835%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: challenge, token: mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ, status: 2%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: order.status 1%0a> acme-client: https://acme-v02.api.letsencrypt.org/acme/finalize/81817869/2815341474: certificate%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: order.status 3%0a> acme-client: https://acme-v02.api.letsencrypt.org/acme/cert/vxsJMODZOeZxwiuyq9Bz6jqgoRRRUak8ZQ3ob: certificate%0a> acme-client: 172.65.32.248: tls_close: EOF without close notify%0a> acme-client: /etc/ssl/example.com.fullchain.pem: created%0a
137 aa513bf8 2023-01-22 jrmu host:1614245123=198.251.81.119
138 aa513bf8 2023-01-22 jrmu author:1614242993=jrmu
139 aa513bf8 2023-01-22 jrmu diff:1614242993:1614242757:=177,203c177,181%0a%3c acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. If [[openhttpd/configure|openhttpd]] is not configured and running properly, acme-client won't work.%0a%3c %0a%3c To test if your web server is running properly, use [[telnet/http|telnet]] (replacing @@example.com@@ with your domain):%0a%3c %0a%3c [@%0a%3c $ telnet example.com 80%0a%3c GET /index.html HTTP/1.1%0a%3c Host: example.com%0a%3c @]%0a%3c %0a%3c You should a response similar to the one below:%0a%3c %0a%3c [@%0a%3c HTTP/1.0 302 Found%0a%3c Date: Tue, 23 Feb 2021 14:01:28 GMT%0a%3c OpenBSD httpd%0a%3c Connection: close%0a%3c Content-Type: text/html%0a%3c Content-Length: 486%0a%3c Location: https://example.com/index.html%0a%3c ...%0a%3c @]%0a%3c %0a%3c If you do not get this response, double check your openhttpd configuration.%0a%3c %0a%3c '''Note''': Using the telnet command above is more reliable than visiting the URL in a web browser. By default, httpd.conf (and most web browsers) will forward all requests to port 80 to port 443. As a result, your web browser will see what is listening on port 443, but the certificate authority will test port 80 only.%0a%3c %0a---%0a> acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. If openhttpd is not configured and running properly, acme-client won't work.%0a> %0a> You **must** have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)%0a> # You have the proper permissions set on the folders in /var/www/. An example output would be,%0a> %0a
140 aa513bf8 2023-01-22 jrmu host:1614242993=198.251.81.119
141 aa513bf8 2023-01-22 jrmu author:1614242757=jrmu
142 aa513bf8 2023-01-22 jrmu diff:1614242757:1614242252:=175,179c175%0a%3c !!! OpenHTTPd Misconfigured%0a%3c %0a%3c acme-client uses the "http-01" challenge. A file is created with a special message in @@/var/www/acme/@@, and the certificate authority requests that file using the URL @@http://example.com/.well-known/acme-challenge/*@@. If openhttpd is not configured and running properly, acme-client won't work.%0a%3c %0a%3c You **must** have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)%0a---%0a> # The [[Openhttpd|web server]] is configured properly. You **must** have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)%0a
143 aa513bf8 2023-01-22 jrmu host:1614242757=198.251.81.119
144 aa513bf8 2023-01-22 jrmu author:1614242252=jrmu
145 aa513bf8 2023-01-22 jrmu diff:1614242252:1614242101:=164,174c164,171%0a%3c # You have the wrong IP addresses.%0a%3c # DNS records are missing.%0a%3c %0a%3c If you have missing records, you will see this response:%0a%3c %0a%3c [@%0a%3c Host example.com not found: 3(NXDOMAIN)%0a%3c @]%0a%3c %0a%3c You will either need to speak with your DNS provider or you will need to troubleshoot [[nsd/troubleshoot|nsd]].%0a%3c %0a---%0a> # %0a> %0a> %0a> Host blahblah.coconut.ircnow.org not found: 3(NXDOMAIN)%0a> %0a> If you %0a> %0a> [[nsd|DNS]] is configured properly%0a
146 aa513bf8 2023-01-22 jrmu host:1614242252=198.251.81.119
147 aa513bf8 2023-01-22 jrmu author:1614242101=jrmu
148 aa513bf8 2023-01-22 jrmu diff:1614242101:1614241008:=144,173c144,149%0a%3c If acme-client fails, there are several possible causes:%0a%3c %0a%3c !!! Missing Domain Records%0a%3c %0a%3c It's possible that your domain records are missing. Run this command, replacing @@example.com@@ with your real hostname:%0a%3c %0a%3c [@%0a%3c $ host example.com%0a%3c @]%0a%3c %0a%3c You should see one or two records like the following:%0a%3c %0a%3c [@%0a%3c example.com has address 93.184.216.34%0a%3c example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946%0a%3c @]%0a%3c %0a%3c The IPv4 and IPv6 address must exactly match the IPs that [[openhttpd/configure|OpenHTTPd]] is listening on. There are a few possible mistakes:%0a%3c %0a%3c # Your web server is listening only one IPv4 but your DNS record includes IPv6; or vice versa.%0a%3c # %0a%3c %0a%3c %0a%3c Host blahblah.coconut.ircnow.org not found: 3(NXDOMAIN)%0a%3c %0a%3c If you %0a%3c %0a%3c [[nsd|DNS]] is configured properly%0a%3c # The [[Openhttpd|web server]] is configured properly. You **must** have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)%0a%3c # You have the proper permissions set on the folders in /var/www/. An example output would be,%0a---%0a> If you run into errors, check to make sure:%0a> %0a> # [[nsd|DNS]] is configured properly. %0a> # The [[Openhttpd|web server]] is configured properly. You **must** have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)%0a> # You have the proper permissions set on the folders in /var/www/. An example output would be,%0a> %0a
149 aa513bf8 2023-01-22 jrmu host:1614242101=198.251.81.119
150 aa513bf8 2023-01-22 jrmu author:1614241008=jrmu
151 aa513bf8 2023-01-22 jrmu diff:1614241008:1614240851:=134,141d133%0a%3c If all goes well, you should see the following line at the very bottom:%0a%3c %0a%3c [@%0a%3c acme-client: /etc/ssl/example.com.fullchain.pem: created%0a%3c @]%0a%3c %0a%3c You should now have two certificates, the public key inside @@/etc/ssl/example.com.fullchain.pem@@, and the private key inside @@/etc/ssl/private/example.com.key@@ (or wherever you changed the path to).%0a%3c %0a143d134%0a%3c %0a
152 aa513bf8 2023-01-22 jrmu host:1614241008=198.251.81.119
153 aa513bf8 2023-01-22 jrmu author:1614240851=jrmu
154 aa513bf8 2023-01-22 jrmu diff:1614240851:1614240518:=113,114c113,114%0a%3c If you want to sign with buypass, test a staging certificate (to avoid using up your rate-limit), or switch to another authority, then edit this line:%0a%3c %0a---%0a> If you want to sign with buypass or another authority instead of Let's Encrypt, then edit this line:%0a> %0a119,124c119%0a%3c Change it to match one of your defined authorities. For example:%0a%3c %0a%3c # To test with letsencrypt-staging, replace it with @@sign with letsencrypt-staging@@.%0a%3c # To sign with buypass, replace it with @@sign with buypass@@.%0a%3c %0a%3c '''Note''': staging certificates are not recognized by most browsers and will be rejected as an invalid certificate. After you finish testing with a staging certificate, you will want to get a properly signed one.%0a---%0a> Change it to match one of your defined authorities.%0a
155 aa513bf8 2023-01-22 jrmu host:1614240851=198.251.81.119
156 aa513bf8 2023-01-22 jrmu author:1614240518=jrmu
157 aa513bf8 2023-01-22 jrmu diff:1614240518:1614239909:=43,44d42%0a%3c To both of these blocks, we will want to add our contact email, so we add @@contact "mailto:me@example.com"@@ inside both blocks:%0a%3c %0a46,49c44,48%0a%3c authority letsencrypt {%0a%3c api url "https://acme-v02.api.letsencrypt.org/directory"%0a%3c account key "/etc/acme/letsencrypt-privkey.pem"%0a%3c contact "mailto:me@example.com"%0a---%0a> domain example.com {%0a> alternative names { secure.example.com }%0a> domain key "/etc/ssl/private/example.com.key"%0a> domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a> sign with letsencrypt%0a51,56d49%0a%3c %0a%3c authority letsencrypt-staging {%0a%3c api url "https://acme-staging-v02.api.letsencrypt.org/directory"%0a%3c account key "/etc/acme/letsencrypt-staging-privkey.pem"%0a%3c contact "mailto:me@example.com"%0a%3c }%0a59,60c52,59%0a%3c Next, the default [[https://man.openbsd.org/acme-client.conf|acme-client.conf]] defines two more authorities:%0a%3c %0a---%0a> This configures acme-client for the domain example.com. You'll want to replace every appearance of @@example.com@@ with your own domain, which might look like @@username.fruit.ircnow.org@@.%0a> %0a> Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@example.ircnow.org@@ and the alternative names @@fruit.ircnow.org@@ and @@vegetable.ircnow.org@@.%0a> %0a> If you use too many alternative names, an acme-client certificate request has a higher chance of failure. So, I recommend keeping the number of alternative names to under 5.%0a> %0a> '''Warning''': Having the @@alternative names@@ directive with nothing inside will cause errors. The below will cause errors:%0a> %0a62,72c61%0a%3c authority buypass {%0a%3c api url "https://api.buypass.com/acme/directory"%0a%3c account key "/etc/acme/buypass-privkey.pem"%0a%3c contact "mailto:me@example.com"%0a%3c }%0a%3c %0a%3c authority buypass-test {%0a%3c api url "https://api.test4.buypass.no/acme/directory"%0a%3c account key "/etc/acme/buypass-test-privkey.pem"%0a%3c contact "mailto:me@example.com"%0a%3c }%0a---%0a> alternative names { }%0a75,76c64,65%0a%3c These two blocks are the same as for letsencrypt, but with the alternative provider [[https://buypass.com/|buypass]]. Make sure to replace the contact email with your own email.%0a%3c %0a---%0a> If you don't need any alternative names, you should comment this line out by putting a # at the beginning of the line, like so:%0a> %0a78,83c67%0a%3c domain example.com {%0a%3c alternative names { secure.example.com }%0a%3c domain key "/etc/ssl/private/example.com.key"%0a%3c domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a%3c sign with letsencrypt%0a%3c }%0a---%0a> # alternative names { }%0a86,93c70,71%0a%3c This configures acme-client for the domain example.com. You'll want to replace every appearance of @@example.com@@ with your own domain, which might look like @@username.fruit.ircnow.org@@.%0a%3c %0a%3c Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@example.ircnow.org@@ and the alternative names @@fruit.ircnow.org@@ and @@vegetable.ircnow.org@@.%0a%3c %0a%3c If you use too many alternative names, an acme-client certificate request has a higher chance of failure. So, I recommend keeping the number of alternative names to under 5.%0a%3c %0a%3c '''Warning''': Having the @@alternative names@@ directive with nothing inside will cause errors. The below will cause errors:%0a%3c %0a---%0a> The @@domain key@@ and @@domain full chain certificate@@ tell acme-client where to put the private key and certificate:%0a> %0a95c73,74%0a%3c alternative names { }%0a---%0a> domain key "/etc/ssl/private/example.com.key"%0a> domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a98,123c77,80%0a%3c If you don't need any alternative names, you should comment this line out by putting a # at the beginning of the line, like so:%0a%3c %0a%3c [@%0a%3c # alternative names { }%0a%3c @]%0a%3c %0a%3c The @@domain key@@ and @@domain full chain certificate@@ tell acme-client where to put the private key and certificate:%0a%3c %0a%3c [@%0a%3c domain key "/etc/ssl/private/example.com.key"%0a%3c domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a%3c @]%0a%3c %0a%3c You will want to replace @@example.com@@ with your real domain. The public key should go inside @@/etc/ssl@@ and the private key should go inside @@/etc/ssl/private@@.%0a%3c %0a%3c If you want to sign with buypass or another authority instead of Let's Encrypt, then edit this line:%0a%3c %0a%3c [@%0a%3c sign with letsencrypt%0a%3c @]%0a%3c %0a%3c Change it to match one of your defined authorities.%0a%3c %0a%3c !! Requesting Certificates%0a%3c %0a%3c After you have finished configuring the conf file, we can request certificates:%0a---%0a> You will want to replace @@example.com@@ with your real domain. The public key should go inside @@/etc/ssl@@ and the private key should go inside @@/etc/ssl/private@@.%0a> %0a> Now, run acme-client:%0a> %0a
158 aa513bf8 2023-01-22 jrmu host:1614240518=198.251.81.119
159 aa513bf8 2023-01-22 jrmu author:1614239909=jrmu
160 aa513bf8 2023-01-22 jrmu diff:1614239909:1614239863:=9c9%0a%3c Note: You must have a server block in [[https://man.openbsd.org/httpd.conf|/etc/httpd.conf]] listening on port 80. Do not delete this block or else acme-client will not work.%0a---%0a> Note: You must have a server block listening on port 80. Do not delete this block or else acme-client will not work.%0a
161 aa513bf8 2023-01-22 jrmu host:1614239909=198.251.81.119
162 aa513bf8 2023-01-22 jrmu author:1614239863=jrmu
163 aa513bf8 2023-01-22 jrmu diff:1614239863:1614239297:=7c7%0a%3c Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning [[dns/overview|DNS records]] for your hostname, which might look like @@username.fruit.ircnow.org@@.%0a---%0a> Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning [[dns/overview|DNS record]], such as @@username.fruit.ircnow.org@@.%0a
164 aa513bf8 2023-01-22 jrmu host:1614239863=198.251.81.119
165 aa513bf8 2023-01-22 jrmu author:1614239297=jrmu
166 aa513bf8 2023-01-22 jrmu diff:1614239297:1614238842:=54,59c54,57%0a%3c Each SSL cert is valid only for a '''common name''' and a set of '''alternative names''' that are provided on the certificate. For example, an SSL certificate might have the common name @@example.ircnow.org@@ and the alternative names @@fruit.ircnow.org@@ and @@vegetable.ircnow.org@@.%0a%3c %0a%3c If you use too many alternative names, an acme-client certificate request has a higher chance of failure. So, I recommend keeping the number of alternative names to under 5.%0a%3c %0a%3c '''Warning''': Having the @@alternative names@@ directive with nothing inside will cause errors. The below will cause errors:%0a%3c %0a---%0a> SSL certs%0a> %0a> Replace example.com with your domain. If you didn't use any alternative names, in the past, having:%0a> %0a64,65c62,63%0a%3c If you don't need any alternative names, you should comment this line out by putting a # at the beginning of the line, like so:%0a%3c %0a---%0a> would cause issues. So, if you have no alternative names, I recommend you comment that line out as follows:%0a> %0a67c65%0a%3c # alternative names { }%0a---%0a> # alternative names { secure.example.com }%0a69,77d66%0a%3c %0a%3c The @@domain key@@ and @@domain full chain certificate@@ tell acme-client where to put the private key and certificate:%0a%3c %0a%3c [@%0a%3c domain key "/etc/ssl/private/example.com.key"%0a%3c domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a%3c @]%0a%3c %0a%3c You will want to replace @@example.com@@ with your real domain. The public key should go inside @@/etc/ssl@@ and the private key should go inside @@/etc/ssl/private@@.%0a
167 aa513bf8 2023-01-22 jrmu host:1614239297=198.251.81.119
168 aa513bf8 2023-01-22 jrmu author:1614238842=jrmu
169 aa513bf8 2023-01-22 jrmu diff:1614238842:1614238762:=51,54d50%0a%3c %0a%3c This configures acme-client for the domain example.com. You'll want to replace every appearance of @@example.com@@ with your own domain, which might look like @@username.fruit.ircnow.org@@.%0a%3c %0a%3c SSL certs%0a
170 aa513bf8 2023-01-22 jrmu host:1614238842=198.251.81.119
171 aa513bf8 2023-01-22 jrmu author:1614238762=jrmu
172 aa513bf8 2023-01-22 jrmu diff:1614238762:1614238543:=30,33c30,33%0a%3c '''Note''': Let's Encrypt [[https://letsencrypt.org/docs/rate-limits/|rate-limits]] the number of SSL certs you can request. If you encounter an error and are unable to request an SSL cert, please fix all errors before requesting again. If you request too many certs in a short time, your domain will get blacklisted for a few hours or days.%0a%3c %0a%3c Although we are using Let's Encrypt for this tutorial, it is important to note that Let's Encrypt currently has a monopoly on free SSL certs. For this reason, IRCNow wants to run its own Certificate Authority in case Let's Encrypt should try to censor our domains.%0a%3c %0a---%0a> '''Note''': Let's Encrypt rate-limits the number of SSL certs you can request.%0a> %0a> Although we are using Let's Encrypt for this tutorial, it is important to note that Let's Encrypt currently has a monopoly on free SSL certs. For this reason, IRCNow is considering running its own Certificate Authority in case Let's Encrypt should try to censor our domains.%0a> %0a41c41%0a%3c letsencrypt-staging is a staging server which you can use to practice requesting fake certificates. The rate limits for the staging server are less strict, so you should practice first with this CA.%0a---%0a> letsencrypt-staging is a staging server which you can use to practice requesting fake certificates.%0a
173 aa513bf8 2023-01-22 jrmu host:1614238762=198.251.81.119
174 aa513bf8 2023-01-22 jrmu author:1614238543=jrmu
175 aa513bf8 2023-01-22 jrmu diff:1614238543:1614238364:=30,33d29%0a%3c '''Note''': Let's Encrypt rate-limits the number of SSL certs you can request.%0a%3c %0a%3c Although we are using Let's Encrypt for this tutorial, it is important to note that Let's Encrypt currently has a monopoly on free SSL certs. For this reason, IRCNow is considering running its own Certificate Authority in case Let's Encrypt should try to censor our domains.%0a%3c %0a39,43c35%0a%3c @]%0a%3c %0a%3c letsencrypt-staging is a staging server which you can use to practice requesting fake certificates.%0a%3c %0a%3c [@%0a---%0a> %0a
176 aa513bf8 2023-01-22 jrmu host:1614238543=198.251.81.119
177 aa513bf8 2023-01-22 jrmu author:1614238364=jrmu
178 aa513bf8 2023-01-22 jrmu diff:1614238364:1614237906:=19,20d18%0a%3c We'll open up /etc/acme-client.conf and analyze the meaning of each block:%0a%3c %0a26,30c24%0a%3c @]%0a%3c %0a%3c This defines the Certificate Authority [[https://letsencrypt.org/|letsencrypt]]. It provides the API URL and the location of the account key.%0a%3c %0a%3c [@%0a---%0a> %0a
179 aa513bf8 2023-01-22 jrmu host:1614238364=198.251.81.119
180 aa513bf8 2023-01-22 jrmu author:1614237906=jrmu
181 aa513bf8 2023-01-22 jrmu diff:1614237906:1614237321:=1,4c1,4%0a%3c (:title Configuring Acme-client:)%0a%3c %0a%3c To enable TLS, you will want a certificate signed by a trusted certificate authority (CA). In this guide, we'll use OpenBSD's [[https://man.openbsd.org/acme-client|acme-client]] with Let's Encrypt.%0a%3c %0a---%0a> (:title Configuring Acme-client)%0a> %0a> To have TLS, you will want a certificate signed by a trusted certificate authority (CA). In this guide, we'll use OpenBSD's [[https://man.openbsd.org/acme-client|acme-client]] with Let's Encrypt.%0a> %0a13c13%0a%3c First, copy the [[https://man.openbsd.org/acme-client.conf|acme-client.conf]] template:%0a---%0a> First, copy the /etc/examples/acme-client.conf template:%0a
182 aa513bf8 2023-01-22 jrmu host:1614237906=198.251.81.119
183 aa513bf8 2023-01-22 jrmu author:1614237321=jrmu
184 aa513bf8 2023-01-22 jrmu diff:1614237321:1614236903:=11c11%0a%3c !! Configuration%0a---%0a> %0a
185 aa513bf8 2023-01-22 jrmu host:1614237321=198.251.81.119
186 aa513bf8 2023-01-22 jrmu author:1614236903=jrmu
187 aa513bf8 2023-01-22 jrmu diff:1614236903:1614236691:=7,8c7,8%0a%3c Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning [[dns/overview|DNS record]], such as @@username.fruit.ircnow.org@@.%0a%3c %0a---%0a> Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning hostname%0a> %0a11c11%0a%3c %0a---%0a> %0a
188 aa513bf8 2023-01-22 jrmu host:1614236903=198.251.81.119
189 aa513bf8 2023-01-22 jrmu author:1614236691=jrmu
190 aa513bf8 2023-01-22 jrmu diff:1614236691:1614236390:=
191 aa513bf8 2023-01-22 jrmu host:1614236691=198.251.81.119
192 aa513bf8 2023-01-22 jrmu author:1614236390=jrmu
193 aa513bf8 2023-01-22 jrmu diff:1614236390:1614076701:=1,11c1,4%0a%3c (:title Configuring Acme-client)%0a%3c %0a%3c To have TLS, you will want a certificate signed by a trusted certificate authority (CA). In this guide, we'll use OpenBSD's [[https://man.openbsd.org/acme-client|acme-client]] with Let's Encrypt.%0a%3c %0a%3c !! Setting up OpenHTTPd%0a%3c %0a%3c Before you begin, you will need to properly configure and start [[openhttpd/configure|openhttpd]]. You will also need a properly functioning hostname%0a%3c %0a%3c Note: You must have a server block listening on port 80. Do not delete this block or else acme-client will not work.%0a%3c %0a%3c %0a---%0a> In order to provide proper TLS for your services, you will need a certificate signed by a trusted certificate authority (CA). The easiest option for now is to use the Let's Encrypt client by acme-client.%0a> %0a> !! Howto%0a> You will need to set up a httpd server in order for the acme-client to work. It is recommended to use openhttpd, click [[Openbsd/Openhttpd|here]] to find out how to set up openhttpd.%0a
194 aa513bf8 2023-01-22 jrmu host:1614236390=198.251.81.119
195 aa513bf8 2023-01-22 jrmu author:1614076701=jrmu
196 aa513bf8 2023-01-22 jrmu diff:1614076701:1614076701:=1,119d0%0a%3c In order to provide proper TLS for your services, you will need a certificate signed by a trusted certificate authority (CA). The easiest option for now is to use the Let's Encrypt client by acme-client.%0a%3c %0a%3c !! Howto%0a%3c You will need to set up a httpd server in order for the acme-client to work. It is recommended to use openhttpd, click [[Openbsd/Openhttpd|here]] to find out how to set up openhttpd.%0a%3c %0a%3c First, copy the /etc/examples/acme-client.conf template:%0a%3c %0a%3c [@%0a%3c $ doas cp /etc/examples/acme-client.conf /etc/acme-client.conf%0a%3c @]%0a%3c %0a%3c [@%0a%3c authority letsencrypt {%0a%3c api url "https://acme-v02.api.letsencrypt.org/directory"%0a%3c account key "/etc/acme/letsencrypt-privkey.pem"%0a%3c }%0a%3c %0a%3c authority letsencrypt-staging {%0a%3c api url "https://acme-staging.api.letsencrypt.org/directory"%0a%3c account key "/etc/acme/letsencrypt-staging-privkey.pem"%0a%3c }%0a%3c %0a%3c domain example.com {%0a%3c alternative names { secure.example.com }%0a%3c domain key "/etc/ssl/private/example.com.key"%0a%3c domain full chain certificate "/etc/ssl/example.com.fullchain.pem"%0a%3c sign with letsencrypt%0a%3c }%0a%3c @]%0a%3c %0a%3c Replace example.com with your domain. If you didn't use any alternative names, in the past, having:%0a%3c %0a%3c [@%0a%3c alternative names { }%0a%3c @]%0a%3c %0a%3c would cause issues. So, if you have no alternative names, I recommend you comment that line out as follows:%0a%3c %0a%3c [@%0a%3c # alternative names { secure.example.com }%0a%3c @]%0a%3c %0a%3c Now, run acme-client:%0a%3c %0a%3c [@%0a%3c $ doas acme-client -Fv example.com%0a%3c @]%0a%3c %0a%3c !! Troubleshooting%0a%3c If you run into errors, check to make sure:%0a%3c %0a%3c # [[nsd|DNS]] is configured properly. %0a%3c # The [[Openhttpd|web server]] is configured properly. You **must** have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)%0a%3c # You have the proper permissions set on the folders in /var/www/. An example output would be,%0a%3c %0a%3c [@%0a%3c $ ls -l /var | grep www%0a%3c drwxr-xr-x 11 root daemon 512 Mar 28 05:28 www%0a%3c $ ls -l /var/www%0a%3c total 36%0a%3c drwxr-xr-x 2 root daemon 512 Mar 28 22:16 acme%0a%3c drwxr-xr-x 2 root daemon 512 Mar 14 06:12 bin%0a%3c drwx-----T 2 www daemon 512 Oct 12 12:34 cache%0a%3c drwxr-xr-x 2 root daemon 512 Mar 14 06:12 cgi-bin%0a%3c drwxr-xr-x 2 root daemon 512 Mar 14 06:03 conf%0a%3c drwxr-xr-x 3 root daemon 512 Oct 12 12:34 htdocs%0a%3c drwxr-xr-x 2 root daemon 512 Mar 29 00:00 logs%0a%3c drwxr-xr-x 2 root daemon 512 Oct 12 12:34 run%0a%3c @]%0a%3c # Your firewall is not configured to block Let's Encrypt certification verification process. Typically it will initiate a few servers to connect to port 80 on your server.%0a%3c %0a%3c !! Successful outcomes%0a%3c A successful outcome would result in:%0a%3c # A ASCII text file, suffixed with .key with your hostname in /etc/ssl/private e.g.%0a%3c [@%0a%3c $ doas ls -l /etc/ssl/private%0a%3c -r-------- 1 root wheel 3272 Mar 28 22:16 example.com.key%0a%3c @]%0a%3c # A PEM certificate under /etc/ssl e.g.%0a%3c [@%0a%3c $ ls -l /etc/ssl/*.pem%0a%3c -r--r--r-- 1 root wheel 3937 Mar 28 22:16 example.com.fullchain.pem%0a%3c @]%0a%3c %0a%3c It would have the following output of running acme-client, generating a certificate for example.com%0a%3c %0a%3c [@%0a%3c acme-client: /etc/ssl/private/example.com.key: generated RSA domain key%0a%3c acme-client: /etc/acme/letsencrypt-privkey.pem: generated RSA account key%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/directory: directories%0a%3c acme-client: acme-v02.api.letsencrypt.org: DNS: 172.65.32.248%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/3674632835%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: challenge, token: mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ, status: 0%0a%3c acme-client: /var/www/acme/mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL: created%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ: challenge%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: order.status 0%0a%3c acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/3674632835%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: challenge, token: mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ, status: 2%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: order.status 1%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/acme/finalize/81817869/2815341474: certificate%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: order.status 3%0a%3c acme-client: https://acme-v02.api.letsencrypt.org/acme/cert/vxsJMODZOeZxwiuyq9Bz6jqgoRRRUak8ZQ3ob: certificate%0a%3c acme-client: 172.65.32.248: tls_close: EOF without close notify%0a%3c acme-client: /etc/ssl/example.com.fullchain.pem: created%0a%3c @]%0a%3c %0a%3c !! Common errors%0a%3c %0a%3c # Do not request domains you don't own%0a%3c # If you change the domains, you need to move the cert and request again%0a\ No newline at end of file%0a
197 aa513bf8 2023-01-22 jrmu host:1614076701=198.251.81.119