commit 7dada940df5811b22ae42582c8ff679f1000c3b9 Author: ducoterra Date: Mon Aug 10 15:45:52 2020 -0400 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a2661ad --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +certs/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ff1128 --- /dev/null +++ b/README.md @@ -0,0 +1,261 @@ +# ETCD Config and Testing + +## Config + +### Generate Certs + +Pick one server to act as the CA. + +Install make + +```bash +sudo apt install make +``` + +Install [go](https://golang.org/doc/install) + +```bash +sudo tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz +export PATH=$PATH:/usr/local/go/bin +``` + +Install [cfssl](https://github.com/cloudflare/cfssl) + +```bash +git clone https://github.com/cloudflare/cfssl +cd cfssl +make -j 4 +sudo mkdir /usr/local/cfssl +sudo mv bin/ /usr/local/cfssl/bin +export PATH=$PATH:/usr/local/cfssl/bin +``` + +Create templates + +```bash +mkdir ~/.cfssl +cd ~/.cfssl +``` + +vim ca-config.json + +```json +{ + "signing": { + "default": { + "usages": [ + "signing", + "key encipherment", + "server auth", + "client auth" + ], + "expiry": "876000h" + } + } +} +``` + +vim ca-csr.json: + +```json +{ + "CN": "etcd", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "O": "autogenerated", + "OU": "etcd cluster", + "L": "duconet" + } + ] +} +``` + +vim req-csr.json: + +```json +{ + "CN": "etcd", + "hosts": [ + "3.14.3.102", + "3.14.3.107", + "127.0.0.1" + ], + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "O": "autogenerated", + "OU": "etcd cluster", + "L": "duconet" + } + ] +} +``` + +Generate CA: + +```bash +sudo mkdir -p /certs +sudo chown -R pi:pi /certs +cfssl gencert -initca ca-csr.json | cfssljson -bare certs/ca +``` + +Generate a Peer and Client Cert: + +```bash +cfssl gencert \ + -ca certs/ca.pem \ + -ca-key certs/ca-key.pem \ + -config ca-config.json \ + req-csr.json | cfssljson -bare certs/client + +cfssl gencert \ + -ca certs/ca.pem \ + -ca-key certs/ca-key.pem \ + -config ca-config.json \ + req-csr.json | cfssljson -bare certs/red + +cp certs/ca.pem certs/client-key.pem certs/client.pem certs/red-key.pem certs/red.pem /certs/ + +cfssl gencert \ + -ca certs/ca.pem \ + -ca-key certs/ca-key.pem \ + -config ca-config.json \ + req-csr.json | cfssljson -bare certs/purple + +scp certs/ca.pem certs/client-key.pem certs/client.pem certs/purple-key.pem certs/purple.pem purple:/certs/ + +cfssl gencert \ + -ca certs/ca.pem \ + -ca-key certs/ca-key.pem \ + -config ca-config.json \ + req-csr.json | cfssljson -bare certs/grey + +scp certs/ca.pem certs/client-key.pem certs/client.pem certs/grey-key.pem certs/grey.pem grey:/certs/ +``` + +## Install ETCD + +[Download the latest version](https://github.com/etcd-io/etcd/releases) + +```bash +tar xf etcd.tar.gz +sudo cp etcd/etcd etcd/etcdctl /usr/local/bin/ +sudo chmod +x /usr/local/bin/etcd /usr/local/bin/etcdctl +``` + +## Start the server + +Create folders: + +```bash +sudo mkdir -p /certs/ +sudo chown -R pi:pi /certs/ +sudo mkdir -p /var/lib/etcd +sudo chown -R pi:pi /var/lib/etcd +sudo chmod -R 700 /var/lib/etcd +``` + +Unencrypted (testing only) + +```bash +etcd --name red --initial-advertise-peer-urls http://3.14.3.102:2380 \ + --listen-peer-urls http://3.14.3.102:2380 \ + --listen-client-urls http://3.14.3.102:2379,http://127.0.0.1:2379 \ + --advertise-client-urls http://3.14.3.102:2379 \ + --initial-cluster-token etcd-cluster-1 \ + --initial-cluster red=http://3.14.3.102:2380 \ + --initial-cluster-state new +``` + +TLS Encrypted + +```bash +export ETCD_UNSUPPORTED_ARCH=arm64 +etcd --name red --initial-advertise-peer-urls https://3.14.3.102:2380 \ + --listen-peer-urls https://3.14.3.102:2380 \ + --listen-client-urls https://3.14.3.102:2379,https://127.0.0.1:2379 \ + --advertise-client-urls https://3.14.3.102:2379 \ + --initial-cluster-token pi-cluster-1 \ + --initial-cluster red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380 \ + --initial-cluster-state new \ + --client-cert-auth --trusted-ca-file=/certs/ca.pem \ + --cert-file=/certs/client.pem --key-file=/certs/client-key.pem \ + --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem \ + --peer-cert-file=/certs/red.pem --peer-key-file=/certs/red-key.pem + +export ETCD_UNSUPPORTED_ARCH=arm64 +etcd --name purple --initial-advertise-peer-urls https://3.14.3.107:2380 \ + --listen-peer-urls https://3.14.3.107:2380 \ + --listen-client-urls https://3.14.3.107:2379,https://127.0.0.1:2379 \ + --advertise-client-urls https://3.14.3.107:2379 \ + --initial-cluster-token pi-cluster-1 \ + --initial-cluster red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380 \ + --initial-cluster-state new \ + --client-cert-auth --trusted-ca-file=/certs/ca.pem \ + --cert-file=/certs/client.pem --key-file=/certs/client-key.pem \ + --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem \ + --peer-cert-file=/certs/purple.pem --peer-key-file=/certs/purple-key.pem +``` + +## Systemd + +```conf +[Unit] +Description=etcd service +Documentation=https://github.com/etcd-io/etcd +After=network.target + +[Service] +User=pi +Type=notify +Environment=ETCD_UNSUPPORTED_ARCH=arm64 +Environment=ETCD_DATA_DIR=/var/lib/etcd +Environment=ETCD_NAME=red +Environment=ETCD_INITIAL_ADVERTISE_PEER_URLS=https://3.14.3.102:2380 +Environment=ETCD_LISTEN_PEER_URLS=https://3.14.3.102:2380 +Environment=ETCD_LISTEN_CLIENT_URLS=https://3.14.3.102:2379,https://127.0.0.1:2379 +Environment=ETCD_ADVERTISE_CLIENT_URLS=https://3.14.3.102:2379 +Environment=ETCD_INITIAL_CLUSTER_TOKEN=pi-cluster-1 +Environment=ETCD_INITIAL_CLUSTER="red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380,grey=https://3.14.3.103:2380" +Environment=ETCD_INITIAL_CLUSTER_STATE=new +Environment=ETCD_TRUSTED_CA_FILE=/certs/ca.pem +Environment=ETCD_CERT_FILE=/certs/client.pem +Environment=ETCD_KEY_FILE=/certs/client-key.pem +Environment=ETCD_PEER_TRUSTED_CA_FILE=/certs/ca.pem +Environment=ETCD_PEER_CERT_FILE=/certs/red.pem +Environment=ETCD_PEER_KEY_FILE=/certs/red-key.pem +ExecStart=/usr/local/bin/etcd --client-cert-auth --peer-client-cert-auth +Restart=on-failure +RestartSec=5 +LimitNOFILE=40000 + +[Install] +WantedBy=multi-user.target +``` + +```bash +sudo systemctl start etcd +sudo systemctl enable etcd +journalctl -u etcd -f +``` + +## Testing + +```bash +scp red:/certs/client.pem red:/certs/client-key.pem red:/certs/ca.pem certs +export ETCDCTL_DIAL_TIMEOUT=3s; +export ETCDCTL_CACERT=./certs/ca.pem; # ca.pem +export ETCDCTL_CERT=./certs/client.pem; # 3.14.3.102.pem +export ETCDCTL_KEY=./certs/client-key.pem; # 3.14.3.102-key.pem +export ETCDCTL_ENDPOINTS=https://3.14.3.102:2379,https://3.14.3.107:2379,https://3.14.3.103; +etcdctl put foo bar +etcdctl get foo +while true; do etcdctl get foo && sleep 1; done; +``` diff --git a/cfssl/ca-config.json b/cfssl/ca-config.json new file mode 100644 index 0000000..a92c610 --- /dev/null +++ b/cfssl/ca-config.json @@ -0,0 +1,13 @@ +{ + "signing": { + "default": { + "usages": [ + "signing", + "key encipherment", + "server auth", + "client auth" + ], + "expiry": "876000h" + } + } +} \ No newline at end of file diff --git a/cfssl/ca-csr.json b/cfssl/ca-csr.json new file mode 100644 index 0000000..a273531 --- /dev/null +++ b/cfssl/ca-csr.json @@ -0,0 +1,14 @@ +{ + "CN": "etcd", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "O": "autogenerated", + "OU": "etcd cluster", + "L": "duconet" + } + ] +} \ No newline at end of file diff --git a/cfssl/req-csr.json b/cfssl/req-csr.json new file mode 100644 index 0000000..621c9bb --- /dev/null +++ b/cfssl/req-csr.json @@ -0,0 +1,19 @@ +{ + "CN": "etcd", + "hosts": [ + "3.14.3.102", + "3.14.3.107", + "127.0.0.1" + ], + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "O": "autogenerated", + "OU": "etcd cluster", + "L": "duconet" + } + ] +} \ No newline at end of file