{"id":2350,"date":"2016-01-28T16:30:32","date_gmt":"2016-01-28T14:30:32","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/install-lets-encrypt-nginx\/"},"modified":"2016-01-28T16:30:32","modified_gmt":"2016-01-28T14:30:32","slug":"install-lets-encrypt-nginx","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/install-lets-encrypt-nginx\/","title":{"rendered":"How to install Let&#8217;s Encrypt on Nginx"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Improving your website security through encryption, even on the most basic servers, can increase your visitors\u2019 trust in your site and your ability to run it. Setting up encryption on your web host has generally been complicated and expensive, which often deters administrators whose web applications might not depend on user input. Let\u2019s Encrypt aims to change this by making implementing encryption on any website easier. They are an open and free project that allows obtaining and installing certificates through simple, automated commands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt is&nbsp;a new Certificate Authority capable of issuing certificates cross-signed by IdentTrust, which allows their end certificates to be accepted by all major browsers. &nbsp;This guide outlines the steps for installing their&nbsp;<a href=\"https:\/\/certbot.eff.org\/#centosrhel7-nginx\" target=\"_blank\" rel=\"noopener\">Certbot client<\/a>&nbsp;and how to use it to manage certificates on your CentOS 7 server running nginx.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Installing Let\u2019s Encrypt client<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt greatly simplifies server management by automating the obtaining of certificates and configuring web services to use them. The client is fully featured and extensible for the Let\u2019s Encrypt Certificate Authority or any other CA that supports the <a href=\"https:\/\/github.com\/ietf-wg-acme\/acme\" target=\"_blank\" rel=\"noopener\">ACME protocol<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On CentOS, the client is available in the Extra Packages for Enterprise Linux (EPEL) which you will need first to install and update.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo&nbsp;yum install epel-release\nsudo yum update<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will also need to have nginx installed and running. Of course, if you are adding certificates onto a previously configured web host, this will already be installed.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo yum install nginx\nsudo systemctl start nginx<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, install the certbot client using the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo yum install certbot python2-certbot-nginx<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once installed, you can use the next command to see test the client is working correctly.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">certbot --help<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Given that the help command works, the client is good to go. Next, follow the instructions below to check that your firewall is configured correctly.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Try UpCloud for free!<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Allow HTTP\/S at firewall<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">CentOS 7 has&nbsp;enabled relatively strict firewall rules by default that do not allow HTTP or HTTPS connections to the host. The Let\u2019s Encrypt client requires access to authenticate the domain name and will fail with the default rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you install the certificates on a previously configured web host, the required rules are probably already set. Confirm the firewall rules with the\u2014- list-services command, and then proceed to the next section to obtain the certificates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enable connections for HTTP and HTTPS services using the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo firewall-cmd --permanent --add-service=http --add-service=https<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, reload the firewall rules to apply the changes.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo firewall-cmd --reload<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can check that the rules were added successfully with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo firewall-cmd --list-services<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">dhcpv6-client http ssh https<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see at least the four services enabled, as shown above. With the firewall configured, you can continue obtaining and installing certificates.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Obtaining&nbsp;a certificate<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt validates the domain installed on, similarly to a traditional CA process, by identifying the server administrator via a public key. The client generates a new key pair when interacting with the Let\u2019s Encrypt servers for the first time and then aims to prove to the CA that the host has control over a particular domain in at least one of the two following ways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Provisioning a DNS record under the domain in question<\/li>\n\n\n\n<li>Provisioning an HTTP resource under a well-known URI on the domain<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">On top of one of the two challenges, the client also must sign a nonce with its private key to prove it controls that key pair.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To help the Let\u2019s Encrypt client accomplish these tasks, it supports several plugins that can be used to obtain and install certificates. Let\u2019s Encrypt supports automated installation on nginx, the certificates can be easily obtained using the <tt>--nginx<\/tt>&nbsp;plugin together with other commands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<tt>--nginx<\/tt> plugin automates obtaining certificates from the CA when using Nginx web server software. To use&nbsp;this plugin on the command line, use the example below. Replace the example domain in red with your own.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo certbot --nginx -d <span style=\"color: #ff0000;\">example.upcloud.com<\/span><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The command starts an interactive configuration script that asks a couple of questions to help with managing certificates.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>You must enter a contact email on the first installation on any specific host.<\/li>\n\n\n\n<li>Then&nbsp;go through the Let\u2019s Encrypt Terms of Service and select Agree if you accept the terms and wish to use the service.<\/li>\n\n\n\n<li>Choose whether you wish to share your email address with the Electronic Frontier Foundation (EFF) for updates on their work.<\/li>\n\n\n\n<li>Lastly, enable redirection to HTTPS to secure your domain fully.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">If the client successfully obtained a certificate, the client output includes a confirmation and certificate expiration date.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you are having problems with the client, make sure you are trying to register a domain or subdomain that currently resolves to your server. Also, check that you have the administrative privileges to run the commands and that your&nbsp;domain is pointing to the correct IP address.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Renewing a certificate<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At the end of the certificate-obtaining script, the output shows the certificate\u2019s expiration date, which is usually three months from the day it was issued. Renewing a certificate is just as easy as obtaining one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The client will only renew certificates close to their expiry date, but you can test that the renewal works using the <tt>--dry-run<\/tt> parameter to simulate the process.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo certbot renew --dry-run<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To renew certificates, simply leave out the simulation parameter.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo certbot renew<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once the renewal is complete, reload&nbsp;your web service using the following command to update the configuration to include the new certificates.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nginx -s reload<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your certificate is now again valid for another 3 months.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Considering the duration of the certificates, you might wish to automate the renewal with a short script like the example below and make it executable.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo vi \/etc\/cron.daily\/letsencrypt-renew<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/sh\nif certbot renew &gt; \/var\/log\/letsencrypt\/renew.log 2&gt;&amp;1 ; then\n   nginx -s reload\nfi\nexit<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo chmod +x \/etc\/cron.daily\/letsencrypt-renew<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The example script runs the renewal while directing the output to a log file and then reloads nginx if the process was successful in completing the renewal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can then automate the script using&nbsp;Crontab.&nbsp;Open the root user crontab for edit with the command underneath.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo crontab -e<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Include a line like the example below in the crontab file, then save and exit.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">01 02,14 * * * \/etc\/cron.daily\/letsencrypt-renew<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt recommends setting the automated renewal script to run twice a day at a random minute within the hour. The above example runs at 02:01 and 14:01, but you can select any time slot you wish.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Revoking a certificate<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you wish to remove&nbsp;a certificate from your server, it can be revoked using the client&#8217;s subcommand.&nbsp;The command below can be used to revoke a particular certificate. Replace the <span style=\"color: #ff0000;\"><tt>domain_name<\/tt><\/span>&nbsp;with the domain which certificate you wish to revoke.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo certbot revoke --cert-path \/etc\/letsencrypt\/live\/<span style=\"color: #ff0000;\">domain_name<\/span>\/cert.pem<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The process does not confirm upon completion, but if you perform it again, you will get a message that the certificate has already been revoked.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Enhancing security<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once the certificate and chain are saved on the server, you can check the Nginx configuration to tune the HTTPS connection further using the new certificates.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Only use secure&nbsp;protocols<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As technologies develop, old versions are disused, and the same applies to security protocols. The old insecure SSLv2 and SSLv3 should be disabled and never used on modern web servers. This is due to the inherent insecurities in these protocols, which is why they have been replaced by the TLS protocols. The example below enables the two most secure TLS versions, 1.1 and 1.2.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssl_protocols TLSv1.1 TLSv1.2;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note that TLS v1.0 is already a legacy protocol and should&nbsp;be avoided. However, older web browsers might still need to be allowed to work. Enable it only if necessary.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Enable HTTP Strict Transport Security (HSTS)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Strict Transport Security safeguards TLS by not allowing insecure communication with the websites that use it. It was designed to ensure security even in the case of configuration problems and implementation errors. HSTS automatically converts all plaintext links to a secure version. It also disables click-through certificate warnings, which indicate an active MITM attack, and prevents users from circumventing the warning.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enable HSTS by using the option shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">add_header Strict-Transport-Security \"max-age=31536000; includeSubdomains\";<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Enhance cypher suites<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The cypher suites enable security between your web server and visitor clients by defining how secure communication occurs.&nbsp;The example configuration below is designed for RSA and ECDSA keys and is a great starting point for improved security.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">By using SSL protocols of SSLv3 or newer, the client tells the web server which cypher suites it supports, and the server chooses one option from that list. The important part of this functionality is that the cyphers on the server are listed in the preferred order from the strongest to the weakest, and the cypher order is honoured. This feature can be enforced by adding the following line in your configuration file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssl_prefer_server_ciphers on;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Diffie-Hellman Ephemeral algorithm<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;Diffie-Hellman algorithm is a way of generating a shared secret between two parties in such a way that the secret cannot be seen by observing the communication. It is a useful technique to create an encryption key between a&nbsp;server and a client, that then uses the shared key to encrypt their traffic. Ephemeral Diffie-Hellman (DHE) differs from static Diffie-Hellman in that it generates a temporary key for every connection and never uses the same key twice. This enables forward secrecy, which means that even if the server&#8217;s long-term private key gets leaked, previous communication will remain secure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generate a strong DHE parameter using the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo openssl dhparam -out \/etc\/ssl\/certs\/dhparam.pem 2048<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The process takes but a moment with a 2048-bit key length. You can also use a 4096-bit length for higher security, but generating&nbsp;a longer parameter will be considerably slower.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssl_dhparam \/etc\/ssl\/certs\/dhparam.pem;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, the output can be used in the Nginx&nbsp;configuration using the above example.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Redirect unencrypted connections<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Optionally, you can redirect your HTTP connections to encrypted HTTPS. By creating the HTTP server segment, as shown in the example below, you can tell your web server to listen for regular HTTP traffic and upgrade these connections to secure ones. Again, replace the <span style=\"color: #ff0000;\"><tt>domain_name<\/tt><\/span>&nbsp;with your web server\u2019s domain. The rest of that segment can remain as is.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">server {\n&nbsp; &nbsp;listen 80;\n&nbsp; &nbsp;server_name <span style=\"color: #ff0000;\">domain_name<\/span>;\n&nbsp; &nbsp;return 301 https:\/\/$server_name$request_uri;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will redirect all connections to the encryption-enabled <tt>https:\/\/<\/tt> part of your site, even with links pointing to the&nbsp;<tt>http:\/\/<span style=\"color: #ff0000;\">domain_name<\/span><\/tt>&nbsp;address.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding it all to the configuration<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With CentOS or other Red Hat variants, Certbot saves the Nginx configuration file to \/etc\/letsencrypt\/options-ssl-nginx.conf, but editing it directly will prevent Certbot from updating the file later. Instead, create a new configuration file with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo vi \/etc\/nginx\/conf.d\/<span style=\"color: #ff0000;\">domain_name<\/span>.conf<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This example configuration sets up a single site listening for HTTPS connections with the added security features explained above. In the example underneath, replace domain_name with your own domain.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># HTTPS server\nserver {\n   listen 443 ssl;\n   server_name <span style=\"color: #ff0000;\">domain_name<\/span>;\n   ssl_certificate \/etc\/letsencrypt\/live\/<span style=\"color: #ff0000;\">domain_name<\/span>\/fullchain.pem;\n   ssl_certificate_key \/etc\/letsencrypt\/live\/<span style=\"color: #ff0000;\">domain_name<\/span>\/privkey.pem;\n   ssl_session_cache shared:SSL:10m;\n   ssl_session_timeout 5m;\n   ssl_protocols TLSv1.1 TLSv1.2;\n   ssl_prefer_server_ciphers on;\n   ssl_dhparam \/etc\/ssl\/certs\/dhparam.pem;\n   ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256;\n   add_header Strict-Transport-Security \"max-age=31536000; includeSubdomains\";\n   location \/ {\n      root \/usr\/share\/nginx\/html;\n      index index.html index.htm;\n   }\n}\n\n# HTTP redirect\nserver {\n&nbsp; &nbsp;listen 80;\n&nbsp; &nbsp;server_name <span style=\"color: #ff0000;\">domain_name<\/span>;\n&nbsp; &nbsp;return 301 https:\/\/$server_name$request_uri;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, save the file and exit the editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To have the changes take effect, you will need to restart nginx.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl restart nginx<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now open your domain in a web browser using <tt>https:\/\/domain_name. Whe<\/tt>n it loads, you will know the installation is working properly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can evaluate server encryption performance with Qualys SSL Labs test site. Enter your domain name into the text field and click the Submit button. The test will take a moment, but when completed, it provides useful information on different areas of your server encryption security and an overall rating.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/qualys_ssl_labs_nginx_score-1.png\" alt=\"Qualys SSL Labs nginx test\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt is still in development and might include certain rate limits for issuing certificates to protect the service against accidental and intentional abuse. You can check further details in the Let\u2019s Encrypt <a href=\"https:\/\/letsencrypt.org\/docs\/rate-limits\/\" target=\"_blank\" rel=\"noopener\">documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Other plugins<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In most cases, simply installing and renewing your certificates as instructed above is enough, but the Let\u2019s Encrypt client also supports some additional plugins for managing your certificates. For example, if you do not have a web service configured yet while obtaining a new certificate, you can use the\u2014-standalone plugin with the <tt>certonly<\/tt>&nbsp;subcommand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide focuses on installing the certificate on Nginx using the\u2014- nginx plugin, though Let\u2019s Encrypt works just as well with other web server software. It also has built-in support for issuing and installing certificates automatically for servers running Apache. Check out our guide for how<a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/install-lets-encrypt-apache\/\" target=\"_blank\" rel=\"noreferrer noopener\"> to install Let\u2019s Encrypt on Apache2<\/a> to learn more.&nbsp;You can also learn about other supported options in the&nbsp;<a href=\"http:\/\/letsencrypt.readthedocs.org\/en\/latest\/using.html\" target=\"_blank\" rel=\"noopener\">documentation<\/a>&nbsp;for Let\u2019s Encrypt.<\/p>\n","protected":false},"author":3,"featured_media":24602,"comment_status":"open","ping_status":"closed","template":"","community-category":[253,250],"class_list":["post-2350","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2350"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2350\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2350"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}