Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP proxy support #290

Merged
merged 7 commits into from
Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* [Sensor Publish Feature](source/sensor-publish/README.md)
* [Provisioning with Secure Elements Feature](source/secure-element/README.md)
* [Logging](source/logging/README.md)
* [HTTP Proxy](docs/HTTP_PROXY.md)
* [Samples](source/samples/):
- [MQTT Pub/Sub Sample Feature](source/samples/pubsub/README.md)
* [Doxygen Documentation](docs/README.md)
Expand Down Expand Up @@ -114,6 +115,7 @@ cmake --build . --target test-aws-iot-device-client
* [File and Directory Permission Requirements](docs/PERMISSIONS.md)
* [Environment Variables](docs/ENV.md)
* [Version](docs/VERSION.md)
* [HTTP Proxy](docs/HTTP_PROXY.md)

## AWS IoT Features
* [Jobs Feature Readme](source/jobs/README.md)
Expand Down
77 changes: 77 additions & 0 deletions docs/HTTP_PROXY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# HTTP Proxy

**Notice:** Running the AWS IoT Device Client will incur usage of AWS IoT services, and is likely to incur charges on your AWS account. Please refer the pricing pages for [AWS IoT Core](https://aws.amazon.com/iot-core/pricing/), [AWS IoT Device Management](https://aws.amazon.com/iot-device-management/pricing/), and [AWS IoT Device Defender](https://aws.amazon.com/iot-device-defender/pricing/) for more details.
* [HTTP Proxy](#http-proxy)
+ [HTTP Proxy Support](#http-proxy-support)
- [How It Works](#how-it-works)
- [Configuring HTTP Proxy via the JSON configuration file](#configuring-http-proxy-via-the-json-configuration-file)
- [Sample HTTP proxy configuration](#sample-http-proxy-configuration)
- [Configuration options](#configuration-options)
- [Permissions](#permissions)
- [Overriding the default configuration file from CLI](#overriding-the-default-configuration-file-from-command-line-interface)

[*Back To The Main Readme*](../../README.md)

## HTTP Proxy Support
The AWS IoT Device Client is free, open-source, modular software written in C++ that customers compile and install on Embedded Linux based IoT devices to access AWS IoT Core, AWS IoT Device Management, and AWS IoT Device Defender features. A common setup in the IoT industry is to have devices in field behind an HTTP proxy where the devices could only connect to the internet via the proxy. The HTTP Proxy support feature allows customers to configure their HTTP proxy server with username and password as authentication method when executing device client sample features.

### How It Works
The AWS IoT Device Client initiates the MQTT connection based on the implementation of aws-iot-device-sdk-cpp-v2. The HTTP proxy support for AWS IoT Device Client enables the tunneling proxy mode provided by the C++ SDK. Upon the start of the IoT Device Client, the `HttpProxyOptions` will be attached to the MQTT connection context together with the proxy IP address, port number, authentication information to connect to AWS IoT via an HTTP proxy.

### Configuring HTTP Proxy via the JSON configuration file
An HTTP Proxy configuration file is a JSON document that uses parameters to describe the proxy options used to interact with AWS IoT.

The default HTTP proxy config file should be placed on your device at `~/.aws-iot-device-client/http-proxy.conf`. AWS IoT Device Client would establish MQTT connect with HTTP proxy **only if the `http-proxy-enabled` flag in the configuration is set to `true`**.
#### Sample HTTP proxy configuration
```
{
"http-proxy-enabled": true,
"http-proxy-host": "10.0.0.140",
"http-proxy-port": "9999",
"http-proxy-auth-method": "UserNameAndPassword",
"http-proxy-username": "MyUserName",
"http-proxy-password": "password12345"
}
```
#### Configuration options
**Required Parameters:**

`http-proxy-enabled`: Whether or not the HTTP proxy is enabled (true/false). We read this value in as boolean so no double quotes required for the value field.

`http-proxy-host`: The host IP address of the http proxy server.

*Note:* It is required that you configure the proxy server's IP address within the reserved private IP address range. Valid range of the private IP address are including as follow:
```
Class A: 10.0.0.0 to 10.255.255.255
Class B: 172.16.0.0 to 172.31.255.255
Class C: 192.168.0.0 to 192.168.255.255
```

`http-proxy-port`: The port which the proxy server will listen on. Port number will be validated to make sure it falls into the valid range of 1 - 65535. Note that we read this field in string format so quotes are required.

`http-proxy-auth-method`: Configure HTTP "Basic Authentication" username and password for accessing the proxy. Access is only granted for authenticated users. Field is case-sensitive. Valid values are `UserNameAndPassword` or `None`.

**Optional Parameter:**

`http-proxy-username`: Username for the HTTP proxy authentication.

`http-proxy-password`: Password for the HTTP proxy authentication.

####Permissions

The HTTP proxy support for AWS IoT Device Client enforces chmod permission code of 600 on the HTTP proxy config files. It is also recommended to set chmod permission to 745 on the directory storing config files.

For more information regarding permission recommandations, check out the [permission readme page]((docs/PERMISSIONS.md))

### Overriding the default configuration file from command line interface

User can switch between different HTTP proxy config files without modifying the default config. To override the default HTTP proxy config under the file path `~/.aws-iot-device-client/http-proxy.conf`, start the AWS IoT Device Client with the `--http-proxy-config` parameter and the file path of the overriding HTTP proxy config file.

```
$ ./aws-iot-device-client --http-proxy-config ~/.aws-iot-device-client/MyProxyConfig1.conf
```
*Note:* User still need to follow the example format of the HTTP proxy configuration file. HTTP proxy will be enabled only if the `http-proxy-enabled` is set to `true`.

*Note:* File and parent folder permissions will also be enforced on the overriding configuration file.

[*Back To The Top*](#http-proxy)
1 change: 1 addition & 0 deletions docs/PERMISSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Config File | 640 | **Yes**
Pub/Sub Files | 600 | **Yes**
Sensor Pubilsh Pathname Socket | 660 | **Yes**
PKCS11 Library File | 640 | **Yes**
HTTP Proxy Config File | 600 | **Yes**

#### Recommended and Required permissions on directories storing respective files
Directory | Chmod Permissions | Required |
Expand Down
36 changes: 36 additions & 0 deletions source/SharedCrtResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#include "SharedCrtResourceManager.h"
#include "Version.h"
#include "aws/crt/http/HttpProxyStrategy.h"
#include "logging/LoggerFactory.h"
#include "util/FileUtils.h"
#include "util/ProxyUtils.h"
#include "util/Retry.h"
#include "util/StringUtils.h"

Expand Down Expand Up @@ -307,6 +309,40 @@ int SharedCrtResourceManager::establishConnection(const PlainConfig &config)
clientConfigBuilder.WithSdkName(SharedCrtResourceManager::BINARY_NAME);
clientConfigBuilder.WithSdkVersion(DEVICE_CLIENT_VERSION);

PlainConfig::HttpProxyConfig proxyConfig = config.httpProxyConfig;
Aws::Crt::Http::HttpClientConnectionProxyOptions proxyOptions;

if (proxyConfig.httpProxyEnabled)
{
proxyOptions.HostName = proxyConfig.proxyHost->c_str();
proxyOptions.Port = proxyConfig.proxyPort.value();

LOGM_INFO(
TAG,
"Attempting to establish MQTT connection with proxy: %s:%u",
proxyConfig.proxyHost->c_str(),
proxyConfig.proxyPort.value());

if (proxyConfig.httpProxyAuthEnabled)
{
LOG_INFO(TAG, "Proxy Authentication is enabled");
Aws::Crt::Http::HttpProxyStrategyBasicAuthConfig basicAuthConfig;
basicAuthConfig.ConnectionType = Aws::Crt::Http::AwsHttpProxyConnectionType::Tunneling;
proxyOptions.AuthType = Aws::Crt::Http::AwsHttpProxyAuthenticationType::Basic;
basicAuthConfig.Username = proxyConfig.proxyUsername->c_str();
basicAuthConfig.Password = proxyConfig.proxyPassword->c_str();
proxyOptions.ProxyStrategy =
Aws::Crt::Http::HttpProxyStrategy::CreateBasicHttpProxyStrategy(basicAuthConfig, Aws::Crt::g_allocator);
}
else
{
LOG_INFO(TAG, "Proxy Authentication is disabled");
proxyOptions.AuthType = Aws::Crt::Http::AwsHttpProxyAuthenticationType::None;
}

clientConfigBuilder.WithHttpProxyOptions(proxyOptions);
}

auto clientConfig = clientConfigBuilder.Build();

if (!clientConfig)
Expand Down
Loading