From f599b6af2319425c0df65aecf0d235e8af83968b Mon Sep 17 00:00:00 2001 From: eum602 Date: Mon, 17 Apr 2023 10:10:10 -0500 Subject: [PATCH 1/3] refactor: move docker configuration to a separate folder --- README.md | 12 ++++++++++-- {besu => docker/besu}/33c8fea/iptables.rules.sh | 0 {besu => docker/besu}/33c8fea/key | 0 {besu => docker/besu}/33c8fea/static-nodes.m4 | 0 {besu => docker/besu}/9ab5623/iptables.rules.sh | 0 {besu => docker/besu}/9ab5623/key | 0 {besu => docker/besu}/Dockerfile | 0 {besu => docker/besu}/besu-entrypoint.sh | 0 {besu => docker/besu}/genesis.json | 0 docker-compose.yml => docker/docker-compose.yml | 0 {setup => docker/setup}/Dockerfile | 0 {stunnel => docker/stunnel}/Dockerfile | 0 {stunnel => docker/stunnel}/README.md | 0 {stunnel => docker/stunnel}/stunnel-entrypoint.sh | 0 14 files changed, 10 insertions(+), 2 deletions(-) rename {besu => docker/besu}/33c8fea/iptables.rules.sh (100%) rename {besu => docker/besu}/33c8fea/key (100%) rename {besu => docker/besu}/33c8fea/static-nodes.m4 (100%) rename {besu => docker/besu}/9ab5623/iptables.rules.sh (100%) rename {besu => docker/besu}/9ab5623/key (100%) rename {besu => docker/besu}/Dockerfile (100%) rename {besu => docker/besu}/besu-entrypoint.sh (100%) rename {besu => docker/besu}/genesis.json (100%) rename docker-compose.yml => docker/docker-compose.yml (100%) rename {setup => docker/setup}/Dockerfile (100%) rename {stunnel => docker/stunnel}/Dockerfile (100%) rename {stunnel => docker/stunnel}/README.md (100%) rename {stunnel => docker/stunnel}/stunnel-entrypoint.sh (100%) diff --git a/README.md b/README.md index 7ee8691..8aa68f8 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,19 @@ -## TLS connections encapsulating Hyperledger Besu RPLx communication +## TLS connections encapsulating Hyperledger Besu RPLx communication + This is a proof of concept for TLS encryption of the communication between two Hyperledger Besu nodes. According to its specification, Ethereum nodes uses RLPx protocol for communication between nodes. This protocol carries encrypted messages using the ECIES method and all cryptographic operations are based on the secp256k1 elliptic curve. Instead of replacing the RLPx protocol, we created a TLS tunnel between the peers, and then we redirected all the RLPx traffic through it. -This proof of concept is builded on top of [stunnel](https://www.stunnel.org/) which relies on the _de facto_ standard [OpenSSL](https://www.openssl.org/) for all the cryptographic operations. +This proof of concept is built on top of [stunnel](https://www.stunnel.org/) which relies on the _de facto_ standard [OpenSSL](https://www.openssl.org/) for all the cryptographic operations. + +## Configuration + +There are two ways to test the TLS tunnel between the peers: + +- using dockers: Follow the instructions as described inside the "docker" folder +- cloud configuration: Follow the instructions as described in the "cloud" folder ## Copyright 2020 LACChain diff --git a/besu/33c8fea/iptables.rules.sh b/docker/besu/33c8fea/iptables.rules.sh similarity index 100% rename from besu/33c8fea/iptables.rules.sh rename to docker/besu/33c8fea/iptables.rules.sh diff --git a/besu/33c8fea/key b/docker/besu/33c8fea/key similarity index 100% rename from besu/33c8fea/key rename to docker/besu/33c8fea/key diff --git a/besu/33c8fea/static-nodes.m4 b/docker/besu/33c8fea/static-nodes.m4 similarity index 100% rename from besu/33c8fea/static-nodes.m4 rename to docker/besu/33c8fea/static-nodes.m4 diff --git a/besu/9ab5623/iptables.rules.sh b/docker/besu/9ab5623/iptables.rules.sh similarity index 100% rename from besu/9ab5623/iptables.rules.sh rename to docker/besu/9ab5623/iptables.rules.sh diff --git a/besu/9ab5623/key b/docker/besu/9ab5623/key similarity index 100% rename from besu/9ab5623/key rename to docker/besu/9ab5623/key diff --git a/besu/Dockerfile b/docker/besu/Dockerfile similarity index 100% rename from besu/Dockerfile rename to docker/besu/Dockerfile diff --git a/besu/besu-entrypoint.sh b/docker/besu/besu-entrypoint.sh similarity index 100% rename from besu/besu-entrypoint.sh rename to docker/besu/besu-entrypoint.sh diff --git a/besu/genesis.json b/docker/besu/genesis.json similarity index 100% rename from besu/genesis.json rename to docker/besu/genesis.json diff --git a/docker-compose.yml b/docker/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to docker/docker-compose.yml diff --git a/setup/Dockerfile b/docker/setup/Dockerfile similarity index 100% rename from setup/Dockerfile rename to docker/setup/Dockerfile diff --git a/stunnel/Dockerfile b/docker/stunnel/Dockerfile similarity index 100% rename from stunnel/Dockerfile rename to docker/stunnel/Dockerfile diff --git a/stunnel/README.md b/docker/stunnel/README.md similarity index 100% rename from stunnel/README.md rename to docker/stunnel/README.md diff --git a/stunnel/stunnel-entrypoint.sh b/docker/stunnel/stunnel-entrypoint.sh similarity index 100% rename from stunnel/stunnel-entrypoint.sh rename to docker/stunnel/stunnel-entrypoint.sh From 6943a0db85db4d9b6ee6f44ddd5d3e4607b80960 Mon Sep 17 00:00:00 2001 From: eum602 Date: Mon, 17 Apr 2023 16:03:19 -0500 Subject: [PATCH 2/3] add instructions to wrap ethereum rlpx communication in a network running on cloud --- .gitignore | 2 + README.md | 2 +- cloud/README.md | 32 +++++++++++ cloud/config/LIBOQS.md | 36 ++++++++++++ cloud/config/README.md | 55 +++++++++++++++++++ cloud/config/STUNNEL.md | 27 +++++++++ .../createStunnelConfigForParticipant.sh | 25 +++++++++ cloud/config/stunnel-config/start-tunnels.sh | 6 ++ .../stunnel-config/stop-tunnels-template.sh | 6 ++ .../stunnel-config-client-template.sh | 32 +++++++++++ .../stunnel-config-server-template.sh | 29 ++++++++++ 11 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 cloud/README.md create mode 100644 cloud/config/LIBOQS.md create mode 100644 cloud/config/README.md create mode 100644 cloud/config/STUNNEL.md create mode 100755 cloud/config/stunnel-config/createStunnelConfigForParticipant.sh create mode 100755 cloud/config/stunnel-config/start-tunnels.sh create mode 100755 cloud/config/stunnel-config/stop-tunnels-template.sh create mode 100755 cloud/config/stunnel-config/stunnel-config-client-template.sh create mode 100755 cloud/config/stunnel-config/stunnel-config-server-template.sh diff --git a/.gitignore b/.gitignore index bbc38e8..889f4a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +node1/ +node2/ *.key *.csr *.crt diff --git a/README.md b/README.md index 8aa68f8..f6a850d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This proof of concept is built on top of [stunnel](https://www.stunnel.org/) whi There are two ways to test the TLS tunnel between the peers: - using dockers: Follow the instructions as described inside the "docker" folder -- cloud configuration: Follow the instructions as described in the "cloud" folder +- cloud configuration: Follow the instructions as described in the [cloud section](cloud/README.md) file. ## Copyright 2020 LACChain diff --git a/cloud/README.md b/cloud/README.md new file mode 100644 index 0000000..812fad2 --- /dev/null +++ b/cloud/README.md @@ -0,0 +1,32 @@ +# RLPX Tunnel configuration - cloud environments + +## Requirements + +- Provide 2 virtual machines(nodes), on each machine install an ethereum client, for example Hyperledger Besu +- Configure those nodes in such a way that both can communicate in a custom ethereum network. + +## Configure tunnels + +1. install [liboqs related packages](config/LIBOQS.md) on each virtual machine. +2. configure [stunnel service file](config/STUNNEL.md) on each node. +3. Configure tls certificates: Create two sets of server certificates by following these [instructions](config/README.md). To simplify the configuration just use the same rootCA to sign each participant certificate. +4. For each set of 'certificate.key'/'certificate.crt', move those to each virtual machine. One set for each virtual machine. Once moved to each virtual machine you have to locate these files inside the folder "node1"/"node2" respectively. Remember that in step 3 you created these folders and moved them to the respective virtual machines. +5. You are almost ready. Now it is time to start the tunnels and direct the traffic to stunnel services. Enter to the virtual machine 1 and enter into the folder "node1" (that you previously moved to that virtual machine). Now from there make sure all sh files are executable. **Note**: The same thing applies for node2. + +## Start tunnels on each machine + +Located on node1 or node2 in virtual machines 1 or 2 respectively execute the following command on each machine: + +```shell +./start-tunnels.sh && systemctl stop pantheon && sleep 4s && systemctl restart pantheon +``` + +In this case the command will start the tunnel, modify the firewall configuration and finally will restart the ethereum client to make the changes effective. In this case the client was configured and customized with the [ansible lacchain configuration](https://lacnet.lacchain.net/using-ansible/) + +## Stop tunnels + +Stopping the tunnel is as simple as: + +```shell +./stop-tunnels.sh && systemctl restart pantheon +``` diff --git a/cloud/config/LIBOQS.md b/cloud/config/LIBOQS.md new file mode 100644 index 0000000..d8fbb25 --- /dev/null +++ b/cloud/config/LIBOQS.md @@ -0,0 +1,36 @@ +# Lacchain Liboqs installation guide: + +- Enter as root + +```shell +sudo -i +``` + +- Update + +```shell +apt-get update && apt-get install --no-install-recommends -yV \ + dpkg-dev \ + wget \ + ca-certificates +``` + +- Install liboqs related packages + +```shell +mkdir /debs/ +wget --directory-prefix=/debs/ https://github.com/lacchain/liboqs-debian/releases/download/0.4.0/liboqs_0.4.0_amd64.deb +wget --directory-prefix=/debs/ https://github.com/lacchain/oqs-openssl-debian/releases/download/OQS-OpenSSL_1_1_1-stable-snapshot-2020-07/libssl1.1_1.1.1g-1+oqs-2020-07_amd64.deb +wget --directory-prefix=/debs/ https://github.com/lacchain/oqs-openssl-debian/releases/download/OQS-OpenSSL_1_1_1-stable-snapshot-2020-07/openssl_1.1.1g-1+oqs-2020-07_amd64.deb +wget --directory-prefix=/debs/ https://github.com/lacchain/liboqs-debian/releases/download/0.4.0/SHA256SUMS +wget https://github.com/lacchain/oqs-openssl-debian/releases/download/OQS-OpenSSL_1_1_1-stable-snapshot-2020-07/SHA256SUMS -O ->> /debs/SHA256SUMS + +cd /debs/ && sha256sum --check --ignore-missing --status SHA256SUMS && dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz +echo "deb [trusted=yes] file:/debs ./" >> /etc/apt/sources.list + +apt update && apt install -y --allow-downgrades \ + libssl1.1=1.1.1g-1+oqs-2020-07 \ + stunnel + +rm -rf /var/lib/apt/lists/* +``` diff --git a/cloud/config/README.md b/cloud/config/README.md new file mode 100644 index 0000000..b24c4ed --- /dev/null +++ b/cloud/config/README.md @@ -0,0 +1,55 @@ +# Certificates + +Before starting make sure you have configured the liboqs related libraries, you can follow these [steps](LIBOQS.md) to have the postquantum openssl version. + +## Root CA + +Let's create a root key compliant with falcon-512, this root key wil be used to sign certificates created by each participant (in our case each virtual machine that hosts the ethereum node) + +### Create Root Key + +#### Falcon-512 (Post quantum resistant) + +```shell +$ openssl genpkey -algorithm falcon512 -out rootCA.key +``` + +### Create and self sign the Root Certificate + +```shell +$ openssl req -x509 -new -nodes -key rootCA.key -subj "/C=US/ST=CA/O=IADB/CN=godmode" -sha512 -days 1024 -out rootCA.crt +``` + +## Server certificate + +Now for each participant (in our case each virtual machine that hosts the ethereum node) lets create a post quantum signed certificate + +### Create server certificate key + +Each participant creates a server.key (their private key) + +#### Falcon-512 + +```shell +$ openssl genpkey -algorithm falcon512 -out certificate.key +``` + +### Create Certificate Signing Request for server + +Now the participant creates a certificate signing request (CSR) + +```shell +$ openssl req -new -sha512 -key certificate.key -subj "/C=US/ST=CA/O=IADB/CN=server" -out certificate.csr +``` + +### Generate the certificate using the CSR and key along with the CA Root key + +Now the root CA signs the CSR by using rootCA key with Falcon512 algorithm + +```shell +$ openssl x509 -req -in certificate.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out certificate.crt -days 500 -sha512 +``` + +## Further steps + +You can repeat the same server certificate generation process using the same root CA key. So at a later point these participants will use it to securely communicate with each other over the internet. diff --git a/cloud/config/STUNNEL.md b/cloud/config/STUNNEL.md new file mode 100644 index 0000000..b34d270 --- /dev/null +++ b/cloud/config/STUNNEL.md @@ -0,0 +1,27 @@ +# Configure Stunnel files + +- Configure stunnel: + +```sh +BESU_NODE_1_IP=10.142.15.194 # update this with the correct ip +BESU_NODE_2_IP=10.168.0.8 # update this with the correct ip +P2P_PORT=60606 # for simplicity use this port for p2p communication between nodes, let's assume 60606 port number is the P2P configured port number +``` + +- Create stunnel files for node 1: Situated on the $root_directory/cloud of this repo execute: + + - for node 1: + + ```sh + DESTINATION_IP=$BESU_NODE_2_IP # the IP of the other node to communicate with + ./config/stunnel-config/createStunnelConfigForParticipant.sh node1 $P2P_PORT $DESTINATION_IP + ``` + + - for node 2: + + ```sh + DESTINATION_IP=$BESU_NODE_1_IP # the IP of the other node to communicate with + ./config/stunnel-config/createStunnelConfigForParticipant.sh node2 $P2P_PORT $DESTINATION_IP + ``` + +- The previous step will generate two folders (node1 and node2) containing the necessary configuration for both nodes in order to allow them to communicate through stunnel. Now you have to copy node1 and node2 folders to the respective virtual machines. diff --git a/cloud/config/stunnel-config/createStunnelConfigForParticipant.sh b/cloud/config/stunnel-config/createStunnelConfigForParticipant.sh new file mode 100755 index 0000000..90716c4 --- /dev/null +++ b/cloud/config/stunnel-config/createStunnelConfigForParticipant.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +function createStunnelConfigFiles() { + nodeDir=$1 + P2P_PORT=$2 + DESTINATION_IP=$3 + + rm -rf $nodeDir + mkdir -p $nodeDir + cp ./config/stunnel-config/start-tunnels.sh $nodeDir + + cp ./config/stunnel-config/stop-tunnels-template.sh $nodeDir/stop-tunnels.sh + sed -i "s/P2P_PORT/$P2P_PORT/g" $nodeDir/stop-tunnels.sh + sed -i "s/DESTINATION_IP/$DESTINATION_IP/g" $nodeDir/stop-tunnels.sh + + + cp ./config/stunnel-config/stunnel-config-client-template.sh $nodeDir/stunnel-config-client.sh + sed -i "s/P2P_PORT/$P2P_PORT/g" $nodeDir/stunnel-config-client.sh + sed -i "s/DESTINATION_IP/$DESTINATION_IP/g" $nodeDir/stunnel-config-client.sh + + cp ./config/stunnel-config/stunnel-config-server-template.sh $nodeDir/stunnel-config-server.sh + sed -i "s/P2P_PORT/$P2P_PORT/g" $nodeDir/stunnel-config-server.sh +} + +createStunnelConfigFiles $1 $2 $3 \ No newline at end of file diff --git a/cloud/config/stunnel-config/start-tunnels.sh b/cloud/config/stunnel-config/start-tunnels.sh new file mode 100755 index 0000000..a95e756 --- /dev/null +++ b/cloud/config/stunnel-config/start-tunnels.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +./stop-tunnels.sh +cd /etc/stunnel +(./stunnel-config-client.sh > /dev/null 2>&1 &) && sleep 2s && (./stunnel-config-server.sh > /dev/null 2>&1 &) && \ +echo "all tunnels have been started, now connection is quantum resistant" diff --git a/cloud/config/stunnel-config/stop-tunnels-template.sh b/cloud/config/stunnel-config/stop-tunnels-template.sh new file mode 100755 index 0000000..61bbd78 --- /dev/null +++ b/cloud/config/stunnel-config/stop-tunnels-template.sh @@ -0,0 +1,6 @@ +#!/bin/sh +echo "Deleting tunnel configured firewal rules" +iptables -t nat -D OUTPUT -p tcp --dport P2P_PORT -d DESTINATION_IP -j DNAT --to-destination 127.0.0.1:4911 2>/dev/null || echo "Rule not found, skipping ..." && \ +iptables -D INPUT -p tcp ! -d localhost --dport P2P_PORT -j DROP 2>/dev/null || echo "Rule not found, skipping ..." && \ +echo "Terminating all tunnels" && \ +for pid in `ps -aux | grep stunnel | awk '{ print $2 }'`; do kill -9 $pid 2>/dev/null || echo "All tunnels were terminated"; done; diff --git a/cloud/config/stunnel-config/stunnel-config-client-template.sh b/cloud/config/stunnel-config/stunnel-config-client-template.sh new file mode 100755 index 0000000..7c4ce41 --- /dev/null +++ b/cloud/config/stunnel-config/stunnel-config-client-template.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +echo "\n*************** CLIENT TUNNEL CONFIGURATION *****************" +echo "Configuring firewall rules" +iptables -t nat -D OUTPUT -p tcp --dport P2P_PORT -d DESTINATION_IP -j DNAT --to-destination 127.0.0.1:4911 2>/dev/null || echo "Rule no found ... skipping deletion" && \ +iptables -D INPUT -p tcp ! -d localhost --dport P2P_PORT -j DROP 2>/dev/null || echo "Rule no found ... skipping deletion" && \ +iptables -t nat -A OUTPUT -p tcp --dport P2P_PORT -d DESTINATION_IP -j DNAT --to-destination 127.0.0.1:4911 && \ +iptables -I INPUT -p tcp ! -d localhost --dport P2P_PORT -j DROP +echo "Starting Client Tunnel" && \ +cat > stunnel.conf <<_EOF_ +debug = 7 +foreground = yes +socket = l:TCP_NODELAY=1 +socket = r:TCP_NODELAY=1 +ciphers=AESGCM +[client] +client = yes +accept = 0.0.0.0:4911 +connect = DESTINATION_IP:4912 +CAfile = /etc/stunnel/rootCA.crt +cert = /etc/stunnel/certificate.crt +key = /etc/stunnel/certificate.key +verify = 2 +_EOF_ + +if ! [ -f certificate.crt ] +then + echo ERROR: service certificate not found 1>&2 + exit 1 +fi + +exec stunnel "$@" diff --git a/cloud/config/stunnel-config/stunnel-config-server-template.sh b/cloud/config/stunnel-config/stunnel-config-server-template.sh new file mode 100755 index 0000000..387d5a1 --- /dev/null +++ b/cloud/config/stunnel-config/stunnel-config-server-template.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +echo "\n*************** SERVER TUNNEL CONFIGURATION *****************" + +cd /etc/stunnel + +cat > stunnel.conf <<_EOF_ +debug = 7 +foreground = yes +socket = l:TCP_NODELAY=1 +socket = r:TCP_NODELAY=1 +ciphers=AESGCM +[server] +client = no +accept = 4912 +connect = 127.0.0.1:P2P_PORT +CAfile = /etc/stunnel/rootCA.crt +cert = /etc/stunnel/certificate.crt +key = /etc/stunnel/certificate.key +verify = 2 +_EOF_ + +if ! [ -f certificate.crt ] +then + echo ERROR: service certificate not found 1>&2 + exit 1 +fi + +exec stunnel "$@" From cea37392afaf06ca613478ac3137ef6ceecd6534 Mon Sep 17 00:00:00 2001 From: Erick Pacheco Pedraza Date: Tue, 18 Apr 2023 11:31:09 -0500 Subject: [PATCH 3/3] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Diego López León --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6a850d..1dac854 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This proof of concept is built on top of [stunnel](https://www.stunnel.org/) whi There are two ways to test the TLS tunnel between the peers: -- using dockers: Follow the instructions as described inside the "docker" folder +- using Docker: Follow the instructions as described inside the "docker" folder - cloud configuration: Follow the instructions as described in the [cloud section](cloud/README.md) file. ## Copyright 2020 LACChain