Skip to content

Commit 4ce981c

Browse files
author
Simon Goldberg
committed
Bitcoin Core initial commit
1 parent cedfdb7 commit 4ce981c

File tree

11 files changed

+3789
-0
lines changed

11 files changed

+3789
-0
lines changed

lib/bitcoin-core/README.md

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
## Sample AWS Blockchain Node Runner app for Bitcoin Nodes
2+
3+
### Overview
4+
5+
This guide walks you through deploying a Bitcoin Core mainnet node in a **Virtual Private Cloud (VPC)** using **Docker**, leveraging **AWS Secrets Manager** for secure credential handling. This configuration ensures robust security and performance while optimizing data transfer costs.
6+
7+
---
8+
9+
### Getting Started
10+
11+
#### Cloning the Repository
12+
13+
First, clone the repository from GitHub to get the necessary files and configurations:
14+
15+
```
16+
git clone https://github.com/aws-samples/aws-blockchain-node-runners.git
17+
cd aws-blockchain-node-runners/lib/bitcoin
18+
```
19+
20+
#### Installing Dependencies
21+
22+
Make sure you have AWS CLI installed and configured. Run the following to install any additional dependencies:
23+
24+
```
25+
npm install
26+
```
27+
28+
### Configuration Management - Generating RPC Authentication
29+
30+
To interact with the Bitcoin Core RPC endpoint within your isolated VPC environment, run the following command before deploying the Bitcoin Node via CDK:
31+
32+
```
33+
node generateRPCAuth.js
34+
```
35+
36+
For a deeper dive and an overview of credential rotation, see [RPC Authentication -- Deep Dive](#rpc-authentication----deep-dive).
37+
38+
39+
### Deploying the Node
40+
41+
To deploy a single node setup, use the following command:
42+
43+
```
44+
npx cdk deploy SingleNodeBitcoinCoreStack
45+
```
46+
47+
For High Availability (HA) node deployment, use:
48+
49+
```
50+
npx cdk deploy HABitcoinCoreNodeStack
51+
```
52+
53+
### Deployment Architectures for Bitcoin Nodes
54+
55+
#### Single Node Setup
56+
57+
- A **Bitcoin node** deployed in a **public subnet** continuously synchronizes with the Bitcoin network using outbound connections through a **NAT Gateway**.
58+
- Outbound communication flows through an **Internet Gateway (IGW)**, but the node itself does not have a **public IP address** or **Elastic IP (EIP)**.
59+
- The **NAT Gateway** translates the node's private IP into a public IP for outbound connections, but inbound connections are blocked. This ensures that the node functions as an **outbound-only node**, increasing security and reducing data transfer costs.
60+
61+
#### High Availability (HA) Setup
62+
63+
- Deploying **multiple Bitcoin nodes** in an **Auto Scaling Group** enhances fault tolerance and availability.
64+
- The nodes communicate internally through **private IP addresses** and synchronize through a shared **Application Load Balancer (ALB)**.
65+
- HA nodes maintain synchronization through the **NAT Gateway** without exposing the RPC endpoint to the public internet.
66+
67+
---
68+
69+
### Optimizing Data Transfer Costs
70+
71+
By deploying as an **outbound-only node**, data transfer costs are significantly reduced since the node does not serve blockchain data to external peers. With its outbound connections, the node(s) are able to maintain full blockchain synchronization.
72+
73+
---
74+
### Accessing and Using RPC with a Single Node Bitcoin Core Instance
75+
76+
To interact with your Bitcoin Core instance, you'll need to use AWS Systems Manager, as direct SSH access is not available.
77+
78+
Follow these steps to make an RPC call:
79+
80+
1. **Access the Instance:**
81+
- Open the AWS Console and navigate to EC2 Instances.
82+
- Locate and select the instance named `SingleNodeBitcoinCoreStack/BitcoinSingleNode`.
83+
- Click the "Connect" button.
84+
- Choose "Session Manager" from the connection options.
85+
- Select "Connect" to establish a session.
86+
87+
2. **Execute an RPC Call:**
88+
Once connected, you can interact with the Bitcoin Core node using Docker commands.
89+
90+
To test the RPC interface, use the following command:
91+
92+
```
93+
sudo docker exec -it bitcoind bitcoin-cli getblockchaininfo
94+
```
95+
96+
This command executes the `getblockchaininfo` RPC method, which returns current state information about the blockchain.
97+
98+
3. **Interpreting Results:**
99+
- The output will provide detailed information about the current state of the blockchain, including the current block height, difficulty, and other relevant data.
100+
- You can use similar commands to execute other RPC methods supported by Bitcoin Core.
101+
102+
---
103+
### Secure RPC with AWS Secrets Manager
104+
105+
To securely interact with the Bitcoin Core RPC endpoint from a private subnet within your isolated VPC environment, AWS Secrets Manager is leveraged for credential storage and retrieval.
106+
107+
**Important**: Ensure that you execute the following commands from within a private subnet in the Bitcoin Core Node VPC. A VPC CloudShell environment is suitable for testing purposes.
108+
109+
#### Retrieving Credentials
110+
First, retrieve the RPC credentials from AWS Secrets Manager:
111+
112+
```
113+
export BTC_RPC_AUTH=$(aws secretsmanager get-secret-value --secret-id bitcoin_rpc_credentials --query SecretString --output text)
114+
```
115+
116+
#### Single node RPC Call using credentials
117+
To make an RPC call to a single Bitcoin node, use the following command. Replace <Bitcoin-Node-Private-IP> with the actual private IP address of your Bitcoin node: `<Bitcoin-Node-Private-IP>`.
118+
119+
```
120+
curl --user "$BTC_RPC_AUTH" \
121+
--data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' \
122+
-H 'content-type: text/plain;' http://<Bitcoin-Node-Private-IP>:8332/
123+
```
124+
125+
#### High Availability (HA) RPC Call using credentials
126+
127+
For high availability setups utilizing an Application Load Balancer (ALB), use the following command. Replace <Load-Balancer-DNS-Name> with your ALB's DNS name:
128+
129+
```
130+
curl --user "$BTC_RPC_AUTH" \
131+
--data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' \
132+
-H 'content-type: text/plain;' \
133+
<Load Balancer DNS Name>
134+
```
135+
136+
---
137+
138+
139+
### **Bitcoin Core: Creating an Encrypted Wallet for Payments**
140+
141+
This guide covers how to create an encrypted Bitcoin Core wallet specifically designed for receiving and managing payments in a secure and efficient way.
142+
143+
---
144+
145+
#### **1. Create an Encrypted Payment Wallet**
146+
147+
To create a wallet specifically for handling payments, use the following command:
148+
149+
```
150+
sudo docker exec -it bitcoind bitcoin-cli createwallet "payments" false false "my_secure_passphrase"
151+
```
152+
153+
- **payments:** The wallet name, indicating its purpose.
154+
- **passphrase:** A secure, memorable phrase to protect your funds.
155+
156+
##### **Why Encrypt?**
157+
- Protects against unauthorized access.
158+
- Ensures funds are safe even if the server is compromised.
159+
160+
---
161+
162+
#### **2. Generate a Receiving Address**
163+
164+
To receive payments, generate a new address. You do not need to unlock the wallet for this step:
165+
166+
```
167+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" getnewaddress "customer1" "bech32"
168+
```
169+
170+
- **customer1:** Label to identify payments from this customer.
171+
- **bech32:** Generates a SegWit address for lower transaction fees.
172+
173+
**Example Output:**
174+
```
175+
bc1qxyzabc123... (Bech32 address)
176+
```
177+
178+
---
179+
180+
#### **3. Monitor Incoming Payments**
181+
182+
To check the balance and verify received payments:
183+
184+
```
185+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" getbalance
186+
```
187+
188+
- Displays the total balance held in the wallet.
189+
190+
To view detailed transactions:
191+
192+
```
193+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" listtransactions
194+
```
195+
196+
---
197+
198+
#### **4. Sending Payments (Requires Unlocking)**
199+
200+
When making a payout or transferring funds, you need to unlock the wallet:
201+
202+
```
203+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" walletpassphrase "my_secure_passphrase" 600
204+
```
205+
206+
- Unlocks the wallet for **600 seconds (10 minutes)**.
207+
208+
#### **Send Bitcoin to a specified address:**
209+
210+
```
211+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" sendtoaddress "bc1qrecipientaddress" 0.01 "Payment for service"
212+
```
213+
214+
- Sends **0.01 BTC** with an optional label for record-keeping.
215+
216+
217+
#### **5. Lock the Wallet After Use**
218+
219+
For enhanced security, immediately lock the wallet after transactions:
220+
221+
```
222+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" walletlock
223+
```
224+
225+
226+
227+
#### **6. Backup the Wallet**
228+
229+
To protect your payment data, back up the encrypted wallet regularly:
230+
231+
```
232+
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" backupwallet "/path/to/backup/payments.dat"
233+
```
234+
235+
236+
#### **Security Tips for Payment Wallets**
237+
- Use strong passphrases and store them securely offline.
238+
- Regularly backup your wallet after creating new addresses or receiving payments.
239+
- Consider setting up automated wallet backups to ensure data integrity.
240+
241+
---
242+
### RPC Authentication -- Deep Dive
243+
244+
The `generateRPCAuth.js` script is responsible for generating secure authentication credentials for your Bitcoin node. This script creates a randomly generated **username** and **password** along with a **salt**. The password and salt are then combined and hashed using the **SHA256** algorithm to produce a secure **hash**. This hash is combined with the username to generate the final **rpcauth** parameter that is appended to the `bitcoin.conf` file.
245+
246+
The final `rpcauth` line in `bitcoin.conf` looks like this:
247+
248+
```
249+
rpcauth=user_258:c220c5f38690bf880f0dd177547e55f7$77c6ec2dd90e792d60450b01a84cc8c2563a7fb1d0fbd73de49be818fde4b407
250+
```
251+
252+
- The **rpcauth** part consists of a **username**, **salt**, and a **hashed password**, providing robust protection in the case that your `bitcoin.conf` is accessed by an unauthorized entity.
253+
- The randomly generated **username** and **password** are securely stored in **AWS Secrets Manager**.
254+
255+
By using this script, it ensures that your node has unique and secure credentials.
256+
257+
### Rotating RPC Secrets
258+
259+
To maintain security, rotate RPC credentials periodically using the `generateRPCAuth.js` script:
260+
261+
```
262+
node generateRPCAuth.js
263+
```
264+
265+
This will update the value of your credentials in Secrets Manager.
266+
267+
**Replacing the Credentials and Restarting the Node to Apply Updates**
268+
269+
- Replace the old `rpcauth` value from the `bitcoin.conf` file with the new one:
270+
```
271+
sudo docker exec -it bitcoind sh -c "sed -i 's/^rpcauth=.*/rpcauth=<new rpcauth string with escape char>/' /root/.bitcoin/bitcoin.conf"
272+
```
273+
- Restart the Bitcoin node to apply changes:
274+
```
275+
sudo docker restart bitcoind
276+
```
277+
278+
#### Verifying the Credential Rotation
279+
280+
Make an RPC call to ensure the new credentials are active:
281+
282+
```
283+
curl --user "$BTC_RPC_AUTH" \
284+
--data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' \
285+
-H 'content-type: text/plain;' http://<Bitcoin-Node-Private-IP>:8332/
286+
```
287+
288+
---
289+
290+
### Monitoring and Troubleshooting
291+
292+
Keep your node healthy by monitoring logs and configurations:
293+
294+
- Check recent logs:
295+
```
296+
sudo docker logs -f --tail 100 bitcoind
297+
```
298+
- View the configuration file:
299+
```
300+
cat /home/bitcoin/.bitcoin/bitcoin.conf
301+
```
302+
- View user data logs:
303+
```
304+
sudo cat /var/log/cloud-init-output.log
305+
```
306+
307+
---
308+
309+
### Additional Tips and Best Practices
310+
311+
- Regularly rotate secrets and always remove old `rpcauth` entries before restarting the node.
312+
- Use **CloudWatch** to monitor node performance and detect issues promptly.
313+
314+
---
315+
316+
### Conclusion
317+
318+
Deploying and managing a Bitcoin node on AWS requires careful configuration to ensure security, cost efficiency, and high availability. By following the best practices outlined in this guide, you can maintain a robust and secure node while minimizing costs. Stay proactive with monitoring and regularly update credentials to keep your node running smoothly.
319+

lib/bitcoin-core/app.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env node
2+
const cdk = require('aws-cdk-lib');
3+
const { SingleNodeBitcoinCoreStack } = require('./lib/single-node-stack');
4+
const { HABitcoinCoreNodeStack } = require('./lib/ha-node-stack');
5+
6+
const app = new cdk.App();
7+
new SingleNodeBitcoinCoreStack(app, 'SingleNodeBitcoinCoreStack');
8+
new HABitcoinCoreNodeStack(app, 'HABitcoinCoreNodeStack');

lib/bitcoin-core/cdk.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"app": "node app.js"
3+
}

0 commit comments

Comments
 (0)