Merge pull request #7 from a5an0/channel-backups

Push channel backups into S3
This commit is contained in:
Alex
2021-09-05 22:58:31 -04:00
committed by GitHub
5 changed files with 9355 additions and 1069 deletions

View File

@@ -32,6 +32,7 @@ By default, the grpc port will not be accessible. There's a security group that
Want to add a second (or third or fourth) node? Go into `bin/thundercloud.ts` and add a line at the end like `new LightningNode(app, 'SecondLightningNode', {stackName: "SecondLightningNode"});`, then do `cdk deploy SecondLightningNode`. Want to add a second (or third or fourth) node? Go into `bin/thundercloud.ts` and add a line at the end like `new LightningNode(app, 'SecondLightningNode', {stackName: "SecondLightningNode"});`, then do `cdk deploy SecondLightningNode`.
## Shutting down the node ## Shutting down the node
1. go into the project root and do `cdk destroy` 1. go into the project root and do `cdk destroy`
There is no step 2. You can also go find the stack in CloudFormation and delete it there. either way works. There is no step 2. You can also go find the stack in CloudFormation and delete it there. either way works.
@@ -42,6 +43,7 @@ There is no step 2. You can also go find the stack in CloudFormation and delete
- When your node first boots, it'll execute `lib/configure-node.sh` as root. This is where lnd gets downloaded and configured. Feel free to tweak it to your needs. - When your node first boots, it'll execute `lib/configure-node.sh` as root. This is where lnd gets downloaded and configured. Feel free to tweak it to your needs.
- All the infrastructure is defined in `lib/lightningnode-stack.ts`. You can add/remove/change things there to your liking. doing a `cdk deploy` will update the stack. Changing some instance properties will result in the node being deleted and recreated. Be careful changing the instance. - All the infrastructure is defined in `lib/lightningnode-stack.ts`. You can add/remove/change things there to your liking. doing a `cdk deploy` will update the stack. Changing some instance properties will result in the node being deleted and recreated. Be careful changing the instance.
- If you need to change the AZs that the stack uses for VPC subnets, check out the `get availabilityZones()` in `lib/lightningnode-stack.ts` - If you need to change the AZs that the stack uses for VPC subnets, check out the `get availabilityZones()` in `lib/lightningnode-stack.ts`
- This stack will also create an S3 bucket to hold static channel backups, and the instance will be configured to upload a channel backup everytime it changes. You can find the name of the bucket in the stack outputs (along wih the IP and keyname). Check out `/etc/incron.d/channelbackup` to see the configuration. The `aws s3 ...` command will run whenever the `~/.lnd/data/chain/bitcoin/mainnet/channel.backup` file is closed after writing.
## FAQ ## FAQ
- Why neutrino? - Why neutrino?

View File

@@ -186,6 +186,18 @@ chown -R ec2-user: /home/ec2-user/bin
# ensure the wallet is unlocked by unlocking it every 5 minutes # ensure the wallet is unlocked by unlocking it every 5 minutes
echo '*/5 * * * * ec2-user /home/ec2-user/.npm-global/bin/bos unlock /home/ec2-user/.lnd/wallet_password' >> /etc/crontab echo '*/5 * * * * ec2-user /home/ec2-user/.npm-global/bin/bos unlock /home/ec2-user/.lnd/wallet_password' >> /etc/crontab
# Setup incron to backup channels whenver they're changed
amazon-linux-extras install -y epel
yum install -y incron jq
REGION=$(curl http://169.254.169.254/latest/meta-data/placement/region)
FILE_PATH=/home/ec2-user/.lnd/data/chain/bitcoin/mainnet/channel.backup
S3_CHAN_BUCKET=$(aws --region=$REGION ssm get-parameter --name lightning.backup.bucketname | jq -r .Parameter.Value)
echo "$FILE_PATH IN_CLOSE_WRITE aws --region=$REGION s3 cp $FILE_PATH s3://$S3_CHAN_BUCKET/channel.backup" > /etc/incron.d/channelbackup
echo "$FILE_PATH IN_MODIFY aws --region=$REGION s3 cp $FILE_PATH s3://$S3_CHAN_BUCKET/channel.backup" >> /etc/incron.d/channelbackup
systemctl enable incrond
systemctl start incrond
# Start lnd! # Start lnd!
systemctl enable lnd.service systemctl enable lnd.service
systemctl start lnd.service systemctl start lnd.service

View File

@@ -4,7 +4,8 @@ import {Asset} from '@aws-cdk/aws-s3-assets';
import { KeyPair } from 'cdk-ec2-key-pair'; import { KeyPair } from 'cdk-ec2-key-pair';
import * as path from 'path'; import * as path from 'path';
import { CfnEIP } from '@aws-cdk/aws-ec2'; import { CfnEIP } from '@aws-cdk/aws-ec2';
import { Bucket } from '@aws-cdk/aws-s3';
import { ParameterTier, StringParameter } from '@aws-cdk/aws-ssm';
export class LightningNode extends cdk.Stack { export class LightningNode extends cdk.Stack {
get availabilityZones(): string[] { get availabilityZones(): string[] {
@@ -24,7 +25,7 @@ export class LightningNode extends cdk.Stack {
// SSH key for the node // SSH key for the node
const key = new KeyPair(this, 'KeyPair' + suffix, { const key = new KeyPair(this, 'KeyPair' + suffix, {
name: 'cdk-keypair', name: 'lightning-keypair' + suffix,
description: 'Key Pair created with CDK Deployment', description: 'Key Pair created with CDK Deployment',
}); });
@@ -93,11 +94,22 @@ export class LightningNode extends cdk.Stack {
}); });
setupScript.grantRead( instance.role ); setupScript.grantRead( instance.role );
const channelBucket = new Bucket(this, "ChannelBackupBucket" + suffix, {});
channelBucket.grantWrite(instance.role);
const bucketNameParam = new StringParameter(this, "BucketNameParam" + suffix, {
parameterName: "lightning.backup.bucketname",
stringValue: channelBucket.bucketName,
tier: ParameterTier.STANDARD
});
bucketNameParam.grantRead(instance.role);
// These outputs get printed when you are done deploying, and can be found in the "Outputs" tab // These outputs get printed when you are done deploying, and can be found in the "Outputs" tab
// of the Cloudformation stack. You can also fetch them programatically. Feel free to add more // of the Cloudformation stack. You can also fetch them programatically. Feel free to add more
new cdk.CfnOutput(this, 'IP Address', { value: instance.instancePublicIp }); new cdk.CfnOutput(this, 'IP Address', { value: instance.instancePublicIp });
new cdk.CfnOutput(this, 'Key Name', { value: key.keyPairName }) new cdk.CfnOutput(this, 'Key Name', { value: key.keyPairName });
new cdk.CfnOutput(this, 'Download Key Command', { value: 'aws secretsmanager get-secret-value --secret-id ec2-ssh-key/cdk-keypair/private --query SecretString --output text > cdk-key.pem && chmod 400 cdk-key.pem' }) new cdk.CfnOutput(this, 'Download Key Command', { value: 'aws secretsmanager get-secret-value --secret-id ec2-ssh-key/lightning-keypair' + suffix + '/private --query SecretString --output text > cdk-key.pem && chmod 400 cdk-key.pem' });
new cdk.CfnOutput(this, 'ssh command', { value: 'ssh -i cdk-key.pem -o IdentitiesOnly=yes ec2-user@' + instance.instancePublicIp }) new cdk.CfnOutput(this, 'ssh command', { value: 'ssh -i cdk-key.pem -o IdentitiesOnly=yes ec2-user@' + instance.instancePublicIp });
new cdk.CfnOutput(this, 'Channel Backup Bucket', { value: channelBucket.bucketName });
} }
} }

10346
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,17 +14,19 @@
"@aws-cdk/assert": "1.120.0", "@aws-cdk/assert": "1.120.0",
"@types/jest": "^26.0.10", "@types/jest": "^26.0.10",
"@types/node": "10.17.27", "@types/node": "10.17.27",
"aws-cdk": "1.120.0",
"jest": "^26.4.2", "jest": "^26.4.2",
"ts-jest": "^26.2.0", "ts-jest": "^26.2.0",
"aws-cdk": "1.120.0",
"ts-node": "^9.0.0", "ts-node": "^9.0.0",
"typescript": "~3.9.7" "typescript": "~3.9.7"
}, },
"dependencies": { "dependencies": {
"@aws-cdk/aws-ec2": "1.120.0",
"@aws-cdk/aws-s3": "1.120.0",
"@aws-cdk/aws-s3-assets": "1.120.0",
"@aws-cdk/aws-ssm": "1.120.0",
"@aws-cdk/core": "1.120.0", "@aws-cdk/core": "1.120.0",
"source-map-support": "^0.5.16", "cdk-ec2-key-pair": "^2.2.1",
"@aws-cdk/aws-ec2": "^1.120.0", "source-map-support": "^0.5.16"
"@aws-cdk/aws-s3-assets": "^1.120.0",
"cdk-ec2-key-pair": "^2.2.1"
} }
} }