Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build/
.cache/
greengrass-build/
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ HTTPS, RDP, and VNC.
1. [Build localproxy](docs/localproxy.md)
2. [Build the component](docs/BUILD.md)
3. [Set up AWS permissions](docs/deployment.md#prerequisites)
4. [Deploy to your device](docs/deployment.md#local-deployment)
4. Deploy to your device:
- [Local deployment](docs/deployment.md#local-deployment)
- [GDK deployment](docs/gdk.md) (recommended)
5. [Create and use tunnels](docs/usage.md)

## Configuration
Expand Down
17 changes: 13 additions & 4 deletions docs/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,20 @@ Or use the build script:
### Test Standalone

```sh
./build/bin/secure-tunnel --help
./build/bin/aws-greengrass-secure-tunnel --help
```

## Component Structure

### For GDK deployment (recommended)

Use the [GDK CLI](../docs/gdk.md) to build and publish:

```sh
gdk component build
gdk component publish
```

### For local deployment

For Greengrass Local deployment, create this directory hierarchy:
Expand All @@ -65,7 +74,7 @@ components
├── artifacts
│ └── aws.greengrass.SecureTunneling
│ └── 1.0.0
│ ├── secure-tunnel
│ ├── aws-greengrass-secure-tunnel
│ └── localproxy
└── recipes
└── aws.greengrass.SecureTunneling-2.0.0.yaml
Expand All @@ -77,12 +86,12 @@ For Greengrass Cloud deployment, create a zip file with this structure:

```
aws.greengrass.SecureTunneling-2.0.0.zip
├── secure-tunnel
├── aws-greengrass-secure-tunnel
└── localproxy
```

and then you can upload the zip to a S3 bucket.

- `secure-tunnel`: Built binary from `./build/bin`
- `aws-greengrass-secure-tunnel`: Built binary from `./build/bin`
- `localproxy`: Binary from [localproxy.md](localproxy.md)
- Recipe: Component configuration file
4 changes: 2 additions & 2 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ journalctl -afu 'ggl.*'

## Cloud Deployment

1. Use `recipe-all.yaml` (or `recipe.yaml` for architecture-specific builds) to
create a private component
1. Use `recipe-prod.yaml` (gdk-cli to create and publish component) to create a
private component
2. Create a new deployment in AWS IoT Greengrass
3. Deploy to target devices

Expand Down
70 changes: 70 additions & 0 deletions docs/gdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# GDK Deployment

This guide covers deploying the component using the Greengrass Development Kit
(GDK).

## Prerequisites

- [GDK CLI](https://github.com/aws-greengrass/aws-greengrass-gdk-cli) installed
- AWS credentials configured
- S3 bucket for component artifacts
- Built binaries (see [BUILD.md](BUILD.md))

Install GDK:

```sh
pip3 install git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git@v1.6.0
```

## Configuration

Edit `gdk-config.json`:

```json
{
"component": {
"aws.greengrass.SecureTunneling": {
"publish": {
"bucket": "your-bucket-name",
"region": "us-east-1"
}
}
}
}
```

## Build

Build the component and create the artifact zip:

```sh
gdk component build
```

## Publish

Upload to S3 and create the component version:

```sh
gdk component publish
```

## Deploy

Create a deployment:

```sh
gdk component list # Verify component is published
```

Then deploy via AWS Console or CLI:

```sh
aws greengrassv2 create-deployment \
--target-arn "arn:aws:iot:REGION:ACCOUNT:thing/THING_NAME" \
--components '{
"aws.greengrass.SecureTunneling": {
"componentVersion": "2.0.0"
}
}'
```
File renamed without changes.
34 changes: 34 additions & 0 deletions gdk-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
set -e

# Get version
VERSION=$(cat version | tr -d '\n')

# Check for localproxy
if [ ! -f run/localproxy ]; then
echo "Error: run/localproxy not found. Please build localproxy first."
exit 1
fi

# Create artifact directory
mkdir -p greengrass-build/artifacts/aws.greengrass.SecureTunneling/NEXT_PATCH

# Copy binaries
cp build/bin/aws-greengrass-secure-tunnel greengrass-build/artifacts/aws.greengrass.SecureTunneling/NEXT_PATCH/
cp run/localproxy greengrass-build/artifacts/aws.greengrass.SecureTunneling/NEXT_PATCH/

# Create zip
cd greengrass-build/artifacts/aws.greengrass.SecureTunneling/NEXT_PATCH
zip aws.greengrass.SecureTunneling.zip aws-greengrass-secure-tunnel localproxy
rm aws-greengrass-secure-tunnel localproxy
cd ../../../..

# Generate recipe
sed -e "s/{COMPONENT_NAME}/aws.greengrass.SecureTunneling/g" \
-e "s/{COMPONENT_VERSION}/$VERSION/g" \
-e "s|BUCKET_NAME|$(jq -r '.component."aws.greengrass.SecureTunneling".publish.bucket' gdk-config.json)|g" \
-e "s|COMPONENT_NAME|aws.greengrass.SecureTunneling|g" \
-e "s|COMPONENT_VERSION|$VERSION|g" \
recipe.yaml > greengrass-build/recipes/recipe.yaml

echo "Build complete: greengrass-build/artifacts/aws.greengrass.SecureTunneling/NEXT_PATCH/aws.greengrass.SecureTunneling.zip"
21 changes: 21 additions & 0 deletions gdk-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"component": {
"aws.greengrass.SecureTunneling": {
"author": "AWS",
"version": "NEXT_PATCH",
"build": {
"build_system": "custom",
"custom_build_command": [
"bash",
"-c",
"cmake -B build -DCMAKE_BUILD_TYPE=MinSizeRel && make -C build -j$(nproc) && ./gdk-build.sh"
]
},
"publish": {
"bucket": "BUCKET_NAME",
"region": "us-east-1"
}
}
},
"gdk_version": "1.6.0"
}
1 change: 1 addition & 0 deletions misc/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ ggdb
ggipc
GLIBCXX
greengrass
greengrassv2
INTERPROCEDURAL
iwyu
journalctl
Expand Down
37 changes: 0 additions & 37 deletions recipe-dev.yaml

This file was deleted.

35 changes: 35 additions & 0 deletions recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
RecipeFormatVersion: "2020-01-25"
ComponentName: "{COMPONENT_NAME}"
ComponentVersion: "{COMPONENT_VERSION}"
ComponentType: "aws.greengrass.generic"
ComponentDescription:
"Enables AWS IoT Secure Tunneling connections that you can use to establish
secure bidirectional communications with Greengrass core devices that are
behind restricted firewalls."
ComponentPublisher: "AWS"
ComponentConfiguration:
DefaultConfiguration:
maxConcurrentTunnels: 20
tunnelTimeoutSeconds: 43200
accessControl:
aws.greengrass.ipc.mqttproxy:
"aws.greengrass.SecureTunneling:mqttproxy:1":
policyDescription: "Access to tunnel notification pubsub topic"
operations:
- "aws.greengrass#SubscribeToIoTCore"
resources:
- "$aws/things/+/tunnels/notify"
Manifests:
- Platform:
os: "linux"
runtime: "*"
Lifecycle:
run: |
{artifacts:decompressedPath}/aws.greengrass.SecureTunneling/aws-greengrass-secure-tunnel --thing-name {iot:thingName} --max-tunnels {configuration:/maxConcurrentTunnels} --timeout {configuration:/tunnelTimeoutSeconds} --artifact-path {artifacts:decompressedPath}/aws.greengrass.SecureTunneling/
Artifacts:
- URI: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/aws.greengrass.SecureTunneling.zip"
Unarchive: "ZIP"
Permission:
Read: "OWNER"
Execute: "OWNER"
Empty file added run/.keep
Empty file.
2 changes: 1 addition & 1 deletion src/subscription.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static void on_tunnel_notification(

static uint8_t arena_mem[4096];
GgArena arena = gg_arena_init(GG_BUF(arena_mem));
GgObject notification;
GgObject notification = { 0 };

GgError ret = gg_json_decode_destructive(payload, &arena, &notification);
if (ret != GG_ERR_OK) {
Expand Down
7 changes: 5 additions & 2 deletions src/tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ static void cleanup_tunnel_slot(TunnelCreationContext **ctx) {
active_tunnels--;
int slot = (int) (*ctx - tunnel_contexts);
tunnel_slots_mask &= ~(1U << slot);
GG_LOGI("Tunnel closed (active tunnels: %d)", active_tunnels);
*ctx = NULL;
}
}
Expand Down Expand Up @@ -128,8 +129,10 @@ static void *tunnel_worker(void *arg) {
}

// Prepare localproxy arguments (without access token)
const char *args[] = { "localproxy", "-r", ctx->region, "-d",
dest_addr, "-v", LOCALPROXY_LOG_LEVEL, NULL };
const char *args[] = { "localproxy", "-r", ctx->region,
"-d", dest_addr, "--destination-client-type",
"V1", "-v", LOCALPROXY_LOG_LEVEL,
NULL };

GG_LOGI(
"Using localproxy for service: %s on port %u", ctx->service, ctx->port
Expand Down