Skip to content

Commit fc2485f

Browse files
author
Sergei Orlow
committed
✨ Publish netlify ssl post
1 parent 5854b20 commit fc2485f

File tree

10 files changed

+145
-26
lines changed

10 files changed

+145
-26
lines changed
474 KB
Loading
169 KB
Loading
Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: 'Using custom SSL certificates with Netlify'
3-
date: '2021-03-05'
3+
date: '2021-03-07'
44
tags:
55
- short-guide
66
- netlify
@@ -11,8 +11,92 @@ song: 'https://music.apple.com/ru/album/sober/1341562656?i=1341562806&l=en'
1111
image: './clouds-billy-huynh.jpg'
1212
imageAlt: 'Billy Huynh (Unsplash)'
1313
description: 'A short guide on how to use custom SSL certificates with Netlify to improve security of your users in the cloud.'
14-
published: false
14+
published: true
1515
imageShare: './og-image.png'
1616
---
1717

18-
WIP
18+
> Netlify quickly conquered hearts of developers with it's convenience and ease of use. If you still don't know what Netlify is - I definitely recommend checking their [welcome page](https://docs.netlify.com). I am not affiliated with Netlify - I do think you should try it out.
19+
20+
## Intro
21+
22+
This post is about SSL certificates with Netlify. If you need some details on what SSL is, [here's a read](https://kinsta.com/knowledgebase/how-ssl-works/). By default, you don't need to care of setting up HTTPS with Netlify - they issue and maintain a [Let's Encrypt](https://docs.netlify.com) certificate for you. But sometimes you need to provide identity information to your users which Let's Encrypt doesn't support. This is when paid certificates come into play.
23+
24+
Apart from that, modern domains like _.dev_ come bundled with a free SSL certificate out of the box, so why not use them?
25+
26+
> Keep in mind that SSL that you get with your domain is **not** forever free - it's only free for the first year.
27+
28+
## If you didn't miss anything
29+
30+
In most cases, if you obtained `certificate.pem`, `private.key` and `cert-ca.pem` (or something like that) for your SSL, you won't have any issues with this as you simply need to put three strings in corresponding inputs - the certificate itself, its private key, and so called Certificate Authority (CA) information. When it comes to Netlify, you just need to:
31+
32+
1. go to netlify.com
33+
2. your site
34+
3. **⚙️ Domain settings**
35+
4. scroll down to **HTTPS** section
36+
5. Click **Install custom certificate**
37+
38+
You should see something like this:
39+
40+
![Netlify "Install custom certificate" form](./netlify-install-custom-certificate.png)
41+
42+
What's going to happen next is quite self-explanatory. Put the contents of `certificate.pem` to the **Certificate** textarea, then put `private.key` content to **Private key** textarea, and I bet you know what to do with the last one. Then smash the `Install certificate` button and you're good. It might take a couple of minutes to apply the changes.
43+
44+
## If it's not that easy
45+
46+
Sometimes, though, you find yourself not having either the CA certificate, or the private key.
47+
48+
### No CA
49+
50+
So, you have the cert and the key, but no CA. It happened to me when I issued SSL using Cloudflare, if I can recall correctly. This may apply to other SSL providers as well. Anyways, this one is easy to fix - you just need to find the correct CA cert with your favourite search engine. E.g. for [Cloudflare](https://cloudflare.com) they can be found [here](https://developers.cloudflare.com/ssl/origin-configuration/origin-ca).
51+
52+
### No Private Key
53+
54+
A bit more complex problem is when you lose/miss/forget to copy-paste your private key. It happens if the SSL provider doesn't give it to you - most probably because they don't have it either. This happens because some providers require you to generate a certificate/key pair yourself. Then you create a CSR (Certificate Signing Request) with that pair and send it to the provider. So, they don't know your private key, and can't share it with you. By definition of `private`.
55+
56+
#### How CSR is usually created
57+
58+
The CSR request looks almost the same as a certificate, a bit shorter. There's a whole bunch of ways to do that, you can check [How to generate CSR code](https://www.namecheap.com/support/knowledgebase/article.aspx/467/14/how-to-generate-csr-certificate-signing-request-code/) by Namecheap if you want to pick the one that fits you the most.
59+
60+
After you send the provider your CSR, they let you download a pack of files, where you can find the certificate, a CA certificate (maybe), but no private key. There might be a `.p7b` file which is also usually referred to as PKCS#7. Or there might be a PKCS#12 file. Or no file at all. And if you have, for instance, a `.p7b` file and you try to put its content to the Netlify **Private key** textarea, you'll get a **_Certificate is not a valid PEM certificate_** error.
61+
62+
#### What if you lose the private key
63+
64+
At this point, there are two options:
65+
66+
- If you created a CSR locally using [Apache OpenSSL](https://www.openssl.org), you need to find the right `private.key`. This should help:
67+
68+
```sh
69+
# Check where OpenSSL saves stuff
70+
$ openssl version -d
71+
72+
# Find all issued keys
73+
# OPENSSLDIR - whatever previous command said OPENSSLDIR is
74+
$ grep -r --exclude-dir=log --exclude-dir=ssh --exclude=*history -I -l -e '-----BEGIN PRIVATE*' -e '-----BEGIN RSA*' -e ‘-----BEGIN EC*’ OPENSSLDIR 2> /dev/null
75+
76+
# Check each key against your certificate
77+
# CERT - path to certificate.pem you want to compare to
78+
# KEY - path to a key found by the previous command
79+
$ (openssl x509 -noout -modulus -in CERT | openssl md5 ;\
80+
openssl rsa -noout -modulus -in KEY | openssl md5) | uniq
81+
```
82+
83+
- If you used a third-party tool, chances are you just missed the private key contents when you were creating a CSR. Go to you provider and request reissuing your SSL cert. Create a new CSR using the same tool and be careful not to skip the private key - just copy it for when you will use it with Netlify.
84+
85+
#### Step-by-step CSR creation with Decoder.link
86+
87+
If you don't want to miss it again, here's a short guide with Decoder.link that allows you to quickly create a CSR:
88+
89+
1. Go to [https://decoder.link/csr_generator](https://decoder.link/csr_generator). No signup required!
90+
91+
2. Fill in the form:
92+
![Decoder Link CSR form](./decoder-link-csr-form.png)
93+
94+
3. Click **Generate**
95+
4. You'll see something like this (poor `test.com`):
96+
![CSR test](./csr.png)
97+
5. Don't rush into clicking the orange button. First open the **PRIVATE KEY** tab and copy the private key somewhere.
98+
![Private key test](./private-key.png)
99+
6. Now come back to CSR, copy it and pass it along to your SSL provider. When all required checks are completed, you will be able to get your SSL certificate files.
100+
7. Take the certificate and CA certificate values from those files, and add the private key we just saved.
101+
102+
That's it, you are now ready to use your custom SSL certificate! 🙌
155 KB
Loading
554 KB
Loading

src/components/footer.js

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import styled from '@emotion/styled'
2+
import { Link } from 'gatsby'
23
import { OutboundLink } from 'gatsby-plugin-google-analytics'
34
import React from 'react'
5+
import { useSiteMetadata } from '../hooks/use-site-metadata'
46

57
const StyledFooter = styled.footer`
68
text-align: center;
@@ -9,20 +11,50 @@ const StyledFooter = styled.footer`
911
color: #ccc;
1012
`
1113

12-
const Link = styled(OutboundLink)`
14+
const ExternalLink = styled(OutboundLink)`
1315
color: #ccc;
1416
`
1517

16-
export const Footer = () => (
17-
<StyledFooter role='contentinfo' itemScope itemType='http://schema.org/WPFooter'>
18-
<Link rel='nofollow' href='https://github.com/orlowdev/orlow.dev'>
19-
Source Code
20-
</Link>
21-
<p>
22-
&copy;&nbsp;<span itemProp='copyrightYear'>2015</span>&nbsp;
23-
<span itemProp='copyrightHolder' itemScope itemType='http://schema.org/Person'>
24-
<span itemProp='name'>Sergei Orlow</span>
25-
</span>
26-
</p>
27-
</StyledFooter>
28-
)
18+
const InternalLink = styled(Link)`
19+
color: #ccc;
20+
`
21+
22+
const FooterLinks = styled.ol`
23+
margin: 0;
24+
`
25+
26+
export const Footer = () => {
27+
const { siteUrl } = useSiteMetadata()
28+
29+
return (
30+
<StyledFooter role='contentinfo' itemScope itemType='http://schema.org/WPFooter'>
31+
<p>
32+
&copy;&nbsp;<span itemProp='copyrightYear'>2021</span>&nbsp;
33+
<span itemProp='copyrightHolder' itemScope itemType='http://schema.org/Person'>
34+
<span itemProp='name'>
35+
<InternalLink to={siteUrl} itemProp='url'>
36+
Sergei Orlow
37+
</InternalLink>
38+
</span>
39+
</span>
40+
</p>
41+
<nav>
42+
<FooterLinks>
43+
<li>
44+
<ExternalLink rel='nofollow' href='https://github.com/orlowdev/orlow.dev'>
45+
Source Code
46+
</ExternalLink>
47+
</li>
48+
<li>
49+
<InternalLink to='/rss.xml' rel='alternate' type='application/rss+xml'>
50+
RSS
51+
</InternalLink>
52+
</li>
53+
<li>
54+
<InternalLink to='/sitemap.xml'>Sitemap</InternalLink>
55+
</li>
56+
</FooterLinks>
57+
</nav>
58+
</StyledFooter>
59+
)
60+
}

src/components/header.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import YouTubeIcon from 'simple-icons/icons/youtube'
88
import GitHubIcon from 'simple-icons/icons/github'
99
import { ExternalRoutes } from '../routes'
1010
import { Link } from 'gatsby'
11-
import { Colours } from '../colours'
1211

1312
const StyledHeader = styled.header`
1413
display: flex;
@@ -41,10 +40,11 @@ const LogoLink = styled(Link)`
4140

4241
const Logo = styled.span`
4342
font-family: Montserrat, system;
43+
font-weight: 900;
4444
font-size: 1rem;
4545
vertical-align: center;
4646
text-decoration: none;
47-
color: ${Colours.PRIMARY};
47+
color: #444;
4848
`
4949

5050
const IconSpan = styled.span`

src/components/time-to-read.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const Wrapper = styled.span`
88

99
export const TimeToRead = ({ timeToRead }) => (
1010
<Wrapper>
11-
Time to Read: {timeToRead} min {'⏱ '.repeat(Math.ceil(timeToRead / 8))}
11+
Time to Read: {timeToRead} min {'⏱'.repeat(Math.ceil(timeToRead / 10))}
1212
</Wrapper>
1313
)
1414

src/layout.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const GlobalStyles = () => (
1818
:root {
1919
--deckgo-highlight-code-carbon-box-shadow: 0 0 15px #0000000f;
2020
--deckgo-highlight-code-carbon-background: #ffffff;
21+
--deckgo-highlight-code-font-family: 'JetBrains Mono', monospace;
22+
--deckgo-highlight-code-padding: 10px 36px;
23+
--deckgo-highlight-code-carbon-toolbar-display: none;
2124
}
2225
2326
@font-face {
@@ -30,7 +33,6 @@ const GlobalStyles = () => (
3033
}
3134
3235
body {
33-
font-family: system;
3436
background-color: #fafafa;
3537
}
3638
@@ -50,7 +52,7 @@ const GlobalStyles = () => (
5052
border: 0;
5153
border-radius: 4px;
5254
background-color: ${Colours.LIGHT};
53-
font-family: 'Fira Code', monospace;
55+
font-family: 'JetBrains Mono', monospace;
5456
}
5557
5658
deckgo-highlight-code {
@@ -104,7 +106,7 @@ const GlobalStyles = () => (
104106
background: ${Colours.LIGHT};
105107
padding: 3px 8px;
106108
border-radius: 50%;
107-
font-family: 'Fira Code', monospace;
109+
font-family: 'JetBrains Mono', monospace;
108110
109111
> a,
110112
a:hover,

src/typography.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ export default new Typography({
77
headerFontFamily: ['Montserrat', 'system'],
88
headerColor: '#333',
99
headerWeight: '900',
10-
bodyFontFamily: ['system'],
10+
bodyWeight: '300',
11+
bodyFontFamily: ['JetBrains Mono', 'system'],
1112
bodyColor: '#444',
1213
googleFonts: [
1314
{
1415
name: 'Montserrat',
1516
styles: ['900'],
1617
},
1718
{
18-
name: 'Fira Code',
19-
styles: ['400'],
19+
name: 'JetBrains Mono',
20+
styles: ['100', '300', '400', '700'],
2021
},
2122
],
2223
})

0 commit comments

Comments
 (0)