From 966e23518e406e314ca1ebdbc8c322eca85aa7aa Mon Sep 17 00:00:00 2001 From: Adam Veldhousen Date: Sat, 28 Jan 2023 21:49:03 -0600 Subject: [PATCH] Squashed commit of the following: commit ae186ff1975f118f7476509146d3d58576126711 Author: Adam Veldhousen Date: Sat Jan 28 20:34:55 2023 -0600 first draft commit 9beca1b180b4b841860fa1f9a7ae04bf1f135abe Author: Adam Veldhousen Date: Sat Jan 28 18:41:56 2023 -0600 first pass commit e1e36aa07d90990c718b232476a53f9ac6e0b5fa Author: Adam Veldhousen Date: Fri Jan 27 23:35:38 2023 -0600 new post --- content/about.md | 2 - content/posts/create-your-own-ca-cert.md | 128 +++++++++++++++++++++++ content/posts/golang-makefiles.md | 26 ++--- 3 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 content/posts/create-your-own-ca-cert.md diff --git a/content/about.md b/content/about.md index f5b7ac2..ce3bc87 100644 --- a/content/about.md +++ b/content/about.md @@ -15,6 +15,4 @@ about technology and other passions of mine. - - Content on this site is [CC-BY-SA](https://creativecommons.org/licenses/by/3.0/) diff --git a/content/posts/create-your-own-ca-cert.md b/content/posts/create-your-own-ca-cert.md new file mode 100644 index 0000000..f95cddc --- /dev/null +++ b/content/posts/create-your-own-ca-cert.md @@ -0,0 +1,128 @@ +--- +title: "Creating and Using a CA Certificate" +description: "" +date: "2023-01-27" +tags: +- SSL +draft: false +--- + +Even though there are plenty of options available for obtaining an SSL certificate, you may want to issue your certificates +and check their validity using your own CA. This is useful for internal domains or doing mTLS for services in your networks. + +Below is how to create a CA certificate and issue certs with it, and how to verify that a certificate was issued with +the CA you generated. + +All examples here use the [OpenSSL command-line tool](https://www.openssl.org/docs/man1.1.1/man1/). + +## Creating the Certificate Authority Certificate and Keys + +First generate the private key and Root CA certificate that we will use to issue certs. + +1. Generate a private key for the CA: +```sh {linenos=false} +openssl genrsa 4096 > ca-key.pem +``` + +2. Generate the X509 CA certificate. Note that if you exclude `-subj` you will get an interactive prompt instead: +```sh {linenos=false} +openssl req -new -x509 -nodes -days 3650 -sha256 \ + -subj "/C=US/O=My Org, Inc./OU=R&D/CN=MyOrgCA" \ + -key ca-key.pem \ + -out ca-cert.pem +``` + +If you want to pass more options to `-subj` the following are the available attribute strings - from [RFC4514 Page 6](https://www.rfc-editor.org/rfc/rfc4514): +```text {linenos=false} + String X.500 AttributeType + ------ -------------------------------------------- + CN commonName (2.5.4.3) + L localityName (2.5.4.7) + ST stateOrProvinceName (2.5.4.8) + O organizationName (2.5.4.10) + OU organizationalUnitName (2.5.4.11) + C countryName (2.5.4.6) + STREET streetAddress (2.5.4.9) + DC domainComponent (0.9.2342.19200300.100.1.25) + UID userId (0.9.2342.19200300.100.1.1) +``` + +At this point you can view the CA certificate in a pretty format: +```sh {linenos=false} +$ openssl x509 -in mydomain.com.crt -text -noout +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 25:28:31:d4:81:a4:1e:74:36:9c:50:e2:3e:dd:d0:a5:be:c9:d3:25 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, O = "My Org, Inc.", OU = R&D, CN = MyOrgCA + Validity + Not Before: Jan 29 02:06:59 2023 GMT + Not After : Jan 26 02:06:59 2033 GMT + Subject: C = US, O = "My Org, Inc.", OU = R&D, CN = MyOrgCA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + ... +``` + + +## Creating the Server's Certificate and Keys + +Now that we have our Root CA certificate we can issue certs for our servers to use. To do this you must first generate a +certificate request, and then sign it with your Root CA cert to generate the final certificate. + +1. Generate the private key and certificate request: +```sh {linenos=false} +openssl req -newkey rsa:4096 -nodes -sha256 \ + -subj "/CN=mysite.myorg.internal" \ + -keyout server-key.pem \ + -out server-req.pem +``` + +If you want to add Subject Alternative Names (SANs) to make your cert valid for multiple DNS names, you can use the encantation below: +```sh {linenos=false} +openssl req -newkey rsa:4096 -nodes -days 3650 -sha256 \ + -subj "/CN=mydomain.com" \ + -reqexts SAN \ + -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:site1.myorg.internal,DNS:site2.myorg.internal")) \ + -key server-key.pem \ + -out server-req.pem +``` + +2. Generate the X509 certificate for the server: + +When setting `-days`, the validity time can be no longer than *398 days (13 months)* or you might see errors. This is for security reasons, +read up on the history behind it [here at global sign](https://www.globalsign.com/en/blog/maximum-ssltls-certificate-validity-now-one-year). + +The flag `-set_serial` is like an ID number for each cert issued by your CA. It must be a positive integer and unique to each cert issued. +Below I'm just using `date +%s` to get a unix timestamp for a simple serial number. + +For further reading see [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.2). + +```sh {linenos=false} +openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \ + -in server-req.pem \ + -out server-cert.pem \ + -CA ca-cert.pem \ + -CAkey ca-key.pem + + +# Or once again, if you need to specify SANs +openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \ + -extfile <(printf "subjectAltName=DNS:site1.myorg.internal,DNS:site2.myorg.internal") \ + -in server-req.pem \ + -out server-cert.pem \ + -CA ca-cert.pem \ + -CAkey ca-key.pem +``` + +## Verifying the Certificate + +1. To verify the server certificate: + +```sh {linenos=false} +$ openssl verify -CAfile ca-cert.pem server-cert.pem +``` diff --git a/content/posts/golang-makefiles.md b/content/posts/golang-makefiles.md index ac5aedd..ddfbf13 100755 --- a/content/posts/golang-makefiles.md +++ b/content/posts/golang-makefiles.md @@ -5,16 +5,16 @@ tags: [make, golang] draft: false --- -[Make is a build automation tool from the late 70's][make-wiki] that's pretty popular in C and C++ world. Thanks to its age and -popularity you can find tons of tutorials and Make is supported on basically every platform out there. I'm going to +[Make is a build automation tool from the late 70's][make-wiki] that's pretty popular in C and C++ world. Thanks to its age and +popularity you can find tons of tutorials and Make is supported on basically every platform out there. I'm going to demonstrate how to set up a basic Makefile for Golang projects that will build, lint and test your code. Make has a few simple rules that make it powerful, it expects that each task you create will be the name of an output file -on disk. This is nice because if a file already exists with the same name as a task then Make will skip doing the work +on disk. This is nice because if a file already exists with the same name as a task then Make will skip doing the work for that task. -## Building +## Building For example if you create the following `Makefile` below and place it in the root of your project and run `make`, you will see a new `hello_world` binary built: @@ -32,7 +32,7 @@ make: 'hello_world' is up to date. So lets add a clean command to clean up the build output: -```makefile {linenos=table,hl_lines=["4-5"]} +```makefile {hl_lines=["4-5"]} hello_world: go build -o hello_world main.go @@ -40,10 +40,10 @@ clean: rm -rf ./hello_world ``` -One issue here is that the `clean` task will only work as long as there isn't a file in the project also named `clean`. +One issue here is that the `clean` task will only work as long as there isn't a file in the project also named `clean`. If you want Make to ignore the file system for this task then you can add an entry to the `.PHONY` list: -```makefile {linenos=table,hl_lines=[7]} +```makefile {hl_lines=[7]} hello_world: go build -o hello_world main.go @@ -56,7 +56,7 @@ clean: ## Testing Next we can run tests. You can define variables in your makefile that run shell commands for their value. I'm running -`go list` and filtering out the `vendor` folder so we can run tests for every package in our project. Remember to add +`go list` and filtering out the `vendor` folder so we can run tests for every package in our project. Remember to add that `test` task to the `.PHONY` list: ```makefile @@ -68,11 +68,11 @@ test: .PHONY: test ``` -## Linting +## Linting -Now that we can build and test our code, lets try to lint it. My lint tool of choice is [golangci-lint][golangcilint] -so I like to add an install task that runs `go get` to install it. To do this I take advantage of a Make feature called -prerequisite tasks, where you can list tasks that are required to execute before another task runs. This makes it easy +Now that we can build and test our code, lets try to lint it. My lint tool of choice is [golangci-lint][golangcilint] +so I like to add an install task that runs `go get` to install it. To do this I take advantage of a Make feature called +prerequisite tasks, where you can list tasks that are required to execute before another task runs. This makes it easy to set up the install task as a dependency of our `lint` command, ensuring its installed every time we run it: ```makefile @@ -94,7 +94,7 @@ your commands in. The `-euo pipefail` runs your commands in a type of [strict mo errors as they happen and make your life debugging shells scripts generally much easier. ```makefile -.SHELLFLAGS := -euo pipefail +.SHELLFLAGS := -euo pipefail PKGS := $(shell go list ./... | grep -v vendor) LINT_BIN := $(GOPATH)/bin/golangci-lint