{"id":1708,"date":"2024-08-14T16:36:38","date_gmt":"2024-08-14T23:36:38","guid":{"rendered":"http:\/\/75.119.134.73\/?p=1708"},"modified":"2024-09-30T15:53:17","modified_gmt":"2024-09-30T22:53:17","slug":"lets-encrypt-ssh","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2024\/08\/14\/lets-encrypt-ssh\/","title":{"rendered":"Let&#8217;s Encrypt SSH"},"content":{"rendered":"\n<p>This post is based on this <a href=\"http:\/\/75.119.134.73\/wp-admin\/post.php?post=64\">post<\/a> &#8220;Containerized WordPress, Migration, and SSL&#8221;. I found it a hassle to install and refresh certificates every year (now it&#8217;s 90 days!).<\/p>\n\n\n\n<p>I want to set up an automated job, which requests to a root CA and installs certs automatically.<\/p>\n\n\n\n<p>Let&#8217;s encrypt is a free trusted CA. This post demonstrates how to integrate it with my blog.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">getssl<\/h2>\n\n\n\n<p>Suggested by <a href=\"https:\/\/letsencrypt.org\/getting-started\/#with-shell-access\">https:\/\/letsencrypt.org\/getting-started\/#with-shell-access<\/a>, when website maintainers have access to shell, certbot is the recommended way to use Let&#8217;s Encrypt. However, certbot requires snap to install itself and snap requires systemd managed system. My website unfortunately is not based on systemd. Thus, I used <a href=\"https:\/\/github.com\/srvrco\/getssl\">getssl<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">root@6e856df8f83c:\/# cat \/etc\/os-release \nPRETTY_NAME=\"Debian GNU\/Linux 11 (bullseye)\"\nNAME=\"Debian GNU\/Linux\"\nVERSION_ID=\"11\"\nVERSION=\"11 (bullseye)\"\nVERSION_CODENAME=bullseye\nID=debian\nHOME_URL=\"https:\/\/www.debian.org\/\"\nSUPPORT_URL=\"https:\/\/www.debian.org\/support\"\nBUG_REPORT_URL=\"https:\/\/bugs.debian.org\/\"\n\nroot@6e856df8f83c:\/var\/www\/html# service --status-all\n [ - ]  apache-htcacheclean\n [ + ]  apache2\n [ - ]  apparmor\n [ - ]  dbus\n [ ? ]  hwclock.sh\n [ - ]  procps\n [ - ]  redis-server\n [ + ]  udev<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"># install getssl\nroot@6e856df8f83c:\/# apt-get install dnsutils\n\nroot@6e856df8f83c:\/# curl --silent https:\/\/raw.githubusercontent.com\/srvrco\/getssl\/latest\/getssl > getssl ; chmod 700 getssl\n\nroot@6e856df8f83c:\/# .\/getssl -c nanzhou.cc\ncreating main config file \/root\/.getssl\/getssl.cfgMaking\ndomain directory - \/root\/.getssl\/nanzhou.cc\ncreating domain config file in \/root\/.getssl\/nanzhou.cc\/getssl.cfg\nAdding SANS=www.nanzhou.cc from certificate installed on nanzhou.cc to new configuration file\ncreated domain config file in \/root\/.getssl\/nanzhou.cc\/getssl.cfg<\/code><\/pre>\n\n\n\n<p>Then set up the getssl configs, <code>\/root\/.getssl\/getssl.cfg <\/code>and <code>\/root\/.getssl\/nanzhou.cc\/getssl.cfg<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">root@b889a5cfe9ea:\/# cat \/root\/.getssl\/getssl.cfg \n# vim: filetype=sh\n#\n# This file is read first and is common to all domains\n#\n# Uncomment and modify any variables you need\n# see https:\/\/github.com\/srvrco\/getssl\/wiki\/Config-variables for details\n#\n# The staging server is best for testing (hence set as default)\n# CA=\"https:\/\/acme-staging-v02.api.letsencrypt.org\"\n# This server issues full certificates, however has rate limits\nCA=\"https:\/\/acme-v02.api.letsencrypt.org\"\n\n# The agreement that must be signed with the CA, if not defined the default agreement will be used\n#AGREEMENT=\"\"\n\n# Set an email address associated with your account - generally set at account level rather than domain.\n#ACCOUNT_EMAIL=\"me@example.com\"\nACCOUNT_KEY_LENGTH=4096\nACCOUNT_KEY=\"\/root\/.getssl\/account.key\"\n\n# Account key and private key types - can be rsa, prime256v1, secp384r1 or secp521r1\n#ACCOUNT_KEY_TYPE=\"rsa\"\nPRIVATE_KEY_ALG=\"rsa\"\n#REUSE_PRIVATE_KEY=\"true\"\n\n# Preferred Chain - use an different certificate root from the default\n# This uses wildcard matching so requesting \"X1\" returns the correct certificate - may need to escape characters\n# Staging options are: \"(STAGING) Doctored Durian Root CA X3\" and \"(STAGING) Pretend Pear X1\"\n# Production options are: \"ISRG Root X1\" and \"ISRG Root X2\"\n#PREFERRED_CHAIN=\"\\(STAGING\\) Pretend Pear X1\"\n\n# Uncomment this if you need the full chain file to include the root certificate (Java keystores, Nutanix Prism)\n#FULL_CHAIN_INCLUDE_ROOT=\"true\"\n\n# The command needed to reload apache \/ nginx or whatever you use.\n# Several (ssh) commands may be given using a bash array:\n# RELOAD_CMD=('ssh:sshuserid@server5:systemctl reload httpd' 'logger getssl for server5 efficient.')\n#RELOAD_CMD=\"\"\n\n# The time period within which you want to allow renewal of a certificate\n#  this prevents hitting some of the rate limits.\n# Creating a file called FORCE_RENEWAL in the domain directory allows one-off overrides\n# of this setting\nRENEW_ALLOW=\"30\"\n\n# Define the server type. This can be https, ftp, ftpi, imap, imaps, pop3, pop3s, smtp,\n# smtps_deprecated, smtps, smtp_submission, xmpp, xmpps, ldaps or a port number which\n# will be checked for certificate expiry and also will be checked after\n# an update to confirm correct certificate is running (if CHECK_REMOTE) is set to true\nSERVER_TYPE=\"https\"\nCHECK_REMOTE=\"true\"\n\n# Use the following 3 variables if you want to validate via DNS\n#VALIDATE_VIA_DNS=\"true\"\n#DNS_ADD_COMMAND=\n#DNS_DEL_COMMAND=\n\n# Unusual configurations (especially split views) may require these.\n# If you have a mixture, these can go in the per-domain getssl.cfg.\n#\n# If you must use an external DNS Server (e.g. due to split views)\n# Specify it here.  Otherwise, the default is to find the zone master.\n# The default will usually work.\n# PUBLIC_DNS_SERVER=\"8.8.8.8\"\n\n# If getssl is unable to determine the authoritative nameserver for a domain\n# it will as you to enter AUTH_DNS_SERVER.  This is a server that\n# can answer queries for the zone - a master or a slave, not a recursive server.\n# AUTH_DNS_SERVER=\"10.0.0.14\"\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">root@b889a5cfe9ea:\/# cat \/root\/.getssl\/nanzhou.cc\/getssl.cfg\n# vim: filetype=sh\n#\n# This file is read second (and per domain if running with the -a option)\n# and overwrites any settings from the first file\n#\n# Uncomment and modify any variables you need\n# see https:\/\/github.com\/srvrco\/getssl\/wiki\/Config-variables for details\n# see https:\/\/github.com\/srvrco\/getssl\/wiki\/Example-config-files for example configs\n#\n# The staging server is best for testing\n# CA=\"https:\/\/acme-staging-v02.api.letsencrypt.org\"\n# This server issues full certificates, however has rate limits\nCA=\"https:\/\/acme-v02.api.letsencrypt.org\"\n\n# Private key types - can be rsa, prime256v1, secp384r1 or secp521r1\n#PRIVATE_KEY_ALG=\"rsa\"\n\n# Additional domains - this could be multiple domains \/ subdomains in a comma separated list\n# Note: this is Additional domains - so should not include the primary domain.\nSANS=\"75.119.134.73\"\n\n# Acme Challenge Location. The first line for the domain, the following ones for each additional domain.\n# If these start with ssh: then the next variable is assumed to be the hostname and the rest the location.\n# An ssh key will be needed to provide you with access to the remote server.\n# Optionally, you can specify a different userid for ssh\/scp to use on the remote server before the @ sign.\n# If left blank, the username on the local server will be used to authenticate against the remote server.\n# If these start with ftp:\/ftpes:\/ftps: then the next variables are ftpuserid:ftppassword:servername:ACL_location\n# These should be of the form \"\/path\/to\/your\/website\/folder\/.well-known\/acme-challenge\"\n# where \"\/path\/to\/your\/website\/folder\/\" is the path, on your web server, to the web root for your domain.\n# ftp: uses regular ftp; ftpes: ftp over explicit TLS (port 21); ftps: ftp over implicit TLS (port 990).\n# ftps\/ftpes support FTPS_OPTIONS, e.g. to add \"--insecure\" to the curl command for hosts with self-signed certificates.\n# You can also user WebDAV over HTTPS as transport mechanism. To do so, start with davs: followed by username,\n# password, host, port (explicitly needed even if using default port 443) and path on the server.\n# Multiple locations can be defined for a file by separating the locations with a semi-colon.\nACL=('\/var\/www\/html\/.well-known\/acme-challenge')\n#     'ssh:server5:\/var\/www\/nanzhou.cc\/web\/.well-known\/acme-challenge'\n#     'ssh:sshuserid@server5:\/var\/www\/nanzhou.cc\/web\/.well-known\/acme-challenge'\n#     'ftp:ftpuserid:ftppassword:nanzhou.cc:\/web\/.well-known\/acme-challenge'\n#     'davs:davsuserid:davspassword:{DOMAIN}:443:\/web\/.well-known\/acme-challenge'\n#     'ftps:ftpuserid:ftppassword:nanzhou.cc:\/web\/.well-known\/acme-challenge'\n#     'ftpes:ftpuserid:ftppassword:nanzhou.cc:\/web\/.well-known\/acme-challenge')\n#ACL=('\/var\/www\/web\/.well-known\/acme-challenge')\n\n# Specify SSH options, e.g. non standard port in SSH_OPTS\n# (Can also use SCP_OPTS and SFTP_OPTS)\n# SSH_OPTS=-p 12345\n\n# Set USE_SINGLE_ACL=\"true\" to use a single ACL for all checks\nUSE_SINGLE_ACL=\"true\"\n\n# Preferred Chain - use an different certificate root from the default\n# This uses wildcard matching so requesting \"X1\" returns the correct certificate - may need to escape characters\n# Staging options are: \"(STAGING) Doctored Durian Root CA X3\" and \"(STAGING) Pretend Pear X1\"\n# Production options are: \"ISRG Root X1\" and \"ISRG Root X2\"\n#PREFERRED_CHAIN=\"\\(STAGING\\) Pretend Pear X1\"\n\n# Uncomment this if you need the full chain file to include the root certificate (Java keystores, Nutanix Prism)\n#FULL_CHAIN_INCLUDE_ROOT=\"true\"\n\n# Location for all your certs, these can either be on the server (full path name)\n# or using ssh \/sftp as for the ACL\nDOMAIN_CERT_LOCATION=\"\/etc\/ssl\/nanzhou.cc.crt\" # this is domain cert\nDOMAIN_KEY_LOCATION=\"\/etc\/ssl\/nanzhou.cc.key\" # this is domain key\nCA_CERT_LOCATION=\"\/etc\/ssl\/chain.crt\" # this is CA cert\n#DOMAIN_CHAIN_LOCATION=\"\" # this is the domain cert and CA cert\n#DOMAIN_PEM_LOCATION=\"\" # this is the domain key, domain cert and CA cert\n\n# The command needed to reload apache \/ nginx or whatever you use.\n# Several (ssh) commands may be given using a bash array:\n# RELOAD_CMD=('ssh:sshuserid@server5:systemctl reload httpd' 'logger getssl for server5 efficient.')\nRELOAD_CMD=\"service apache2 reload\"\n\n# Uncomment the following line to prevent non-interactive renewals of certificates\n#PREVENT_NON_INTERACTIVE_RENEWAL=\"true\"\n\n# Define the server type. This can be https, ftp, ftpi, imap, imaps, pop3, pop3s, smtp,\n# smtps_deprecated, smtps, smtp_submission, xmpp, xmpps, ldaps or a port number which\n# will be checked for certificate expiry and also will be checked after\n# an update to confirm correct certificate is running (if CHECK_REMOTE) is set to true\nSERVER_TYPE=\"https\"\nCHECK_REMOTE=\"true\"\n#CHECK_REMOTE_WAIT=\"2\" # wait 2 seconds before checking the remote server\n<\/code><\/pre>\n\n\n\n<p>Finally run <code>getssl<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">root@b889a5cfe9ea:\/# .\/getssl nanzhou.cc\nThe current repository has no releases or is improperly tagged; can't check for upgrades: ''\nRegistering account\nVerify each domain\nVerifying nanzhou.cc\nnanzhou.cc is already validated\nVerifying www.nanzhou.cc\nwww.nanzhou.cc is already validated\nVerification completed, obtaining certificate.\nRequesting Finalize Link\nRequesting Order Link\nACME server still Processing certificates\nRequesting certificate\nCertificate saved in \/root\/.getssl\/nanzhou.cc\/nanzhou.cc.crt\ncopying domain certificate to \/etc\/ssl\/nanzhou.cc.crt\ncopying private key to \/etc\/ssl\/nanzhou.cc.key\ncopying CA certificate to \/etc\/ssl\/chain.crt\nreloading SSL services\nRestarting Apache httpd web server: apache2\n\n<\/code><\/pre>\n\n\n\n<p>At this moment, you should see the website is starting using the new issued credentials.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cron Job<\/h2>\n\n\n\n<p>Use <a href=\"https:\/\/www.man7.org\/linux\/man-pages\/man8\/cron.8.html\">cron<\/a> to schedule refresh regularly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">root@b889a5cfe9ea:\/# crontab -l\n# Edit this file to introduce tasks to be run by cron.\n# \n# Each task to run has to be defined through a single line\n# indicating with different fields when the task will be run\n# and what command to run for the task\n# \n# To define the time you can provide concrete values for\n# minute (m), hour (h), day of month (dom), month (mon),\n# and day of week (dow) or use '*' in these fields (for 'any').\n# \n# Notice that tasks will be started based on the cron's system\n# daemon's notion of time and timezones.\n# \n# Output of the crontab jobs (including errors) is sent through\n# email to the user the crontab file belongs to (unless redirected).\n# \n# For example, you can run a backup of all your user accounts\n# at 5 a.m every week with:\n# 0 5 * * 1 tar -zcf \/var\/backups\/home.tgz \/home\/\n# \n# For more information see the manual pages of crontab(5) and cron(8)\n# \n# m h  dom mon dow   command\n0 0 * * * \/getssl nanzhou.cc\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This post is based on this post &#8220;Containerized WordPress, Migration, and SSL&#8221;. I found it a hassle to install and refresh certificates every year (now it&#8217;s 90 days!). I want to set up an automated job, which requests to a root CA and installs certs automatically. Let&#8217;s encrypt is a free trusted CA. This post&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"0","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13,71],"tags":[],"class_list":["post-1708","post","type-post","status-publish","format-standard","hentry","category-web","category-wordpress"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1708","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=1708"}],"version-history":[{"count":6,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1708\/revisions"}],"predecessor-version":[{"id":1715,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1708\/revisions\/1715"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=1708"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=1708"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=1708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}