Showing posts with label AWS. Show all posts
Showing posts with label AWS. Show all posts

Tuesday, June 13, 2023

Complete Tutorial on Creating & Encoding a CSR in AWS IoT Using Bouncy Castle Library

Chapter 1. Introduction to AWS IoT Provisioning and Bouncy Castle

With the advancement of the internet, Internet of Things (IoT) has spread throughout our daily lives. In this context, Amazon Web Services (AWS) provides stable and scalable IoT services, and one of them is AWS IoT provisioning.

AWS IoT provisioning refers to the secure registration and management of devices. During this process, Certificate Signing Request (CSR) generation is necessary, which is a crucial element used to authenticate the identity of the device.

Introduction to Bouncy Castle

Bouncy Castle is a lightweight encryption API based on Java and C#. It supports a wide range of encryption algorithms and is widely used among developers. It is also useful for CSR generation.

In the next chapter, we will provide a detailed explanation of the CSR generation process using Bouncy Castle.

Return to Table of Contents

Chapter 2. CSR Generation Process Using Bouncy Castle

The process of generating CSR using Bouncy Castle is as follows:

1. Installing the Bouncy Castle Library

First, you need to install the Bouncy Castle library. In Java-based applications, you can download it directly from the Maven repository.

2. Generating Key Pair

Generate an RSA key pair using the Bouncy Castle API. This key pair will be used when making CSR requests.

3. Creating CSR Request Information

Create CSR request information, including the device information to be registered with AWS IoT.

4. CSR Generation and Signing

Use the Bouncy Castle API to generate CSR with the prepared information and sign it with the private key.

These steps are the most crucial in the AWS IoT provisioning process. In the next chapter, we will enhance our understanding through real examples.

Return to Table of Contents

Chapter 3. Understanding CSR Generation Process with Real Examples

In this chapter, we will closely examine the CSR generation process using Bouncy Castle through real code examples.

1. Installing the Bouncy Castle Library

For Maven projects, add the following dependency to the pom.xml file:

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.68</version>
    </dependency>
  

2. Generating Key Pair

Here is the code for generating an RSA key pair using the Bouncy Castle API:

    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
    keyPairGenerator.initialize(2048, new SecureRandom());
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
  

3. Creating CSR Request Information

Here is the code for creating CSR request information, including device information to be registered with AWS IoT:

X500Name subject = new X500Name("CN=Your Device,O=Your Organization,L=Your City,C=Your Country");

4. CSR Generation and Signing

Here is the code for generating CSR with the prepared information and signing it with the private key:

    PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
    JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
    ContentSigner signer = csBuilder.build(keyPair.getPrivate());
    PKCS10CertificationRequest csr = p10Builder.build(signer);
  

In this chapter, we have provided a detailed explanation of how to generate CSR using Bouncy Castle in the AWS IoT provisioning process. In the final chapter, we will conclude and summarize this content.

Return to Table of Contents

Chapter 4. Conclusion and Summary

In this chapter, we have explored how to generate CSR using Bouncy Castle in the AWS IoT provisioning process. AWS IoT provisioning involves the secure registration and management of devices, and CSR (Certificate Signing Request) generation is a crucial part of this process. You can use the Bouncy Castle API to generate CSR and sign it with the private key.

We have examined this process in detail with real code examples. We hope that this has increased your understanding of AWS IoT provisioning and the utilization of Bouncy Castle.

Return to Table of Contents

AWS IoT 프로비저닝 과정에서 Bouncy Castle을 활용한 CSR 생성

1장. AWS IoT 프로비스닝과 Bouncy Castle 소개

인터넷의 발전과 함께 IoT(Internet of Things)가 우리 생활 곳곳에 두루 퍼지고 있습니다. 이런 상황에서 AWS(Amazon Web Services)는 안정적이고 확장 가능한 IoT 서비스를 제공하며, 그 중 하나가 바로 AWS IoT 프로비저닝입니다.

AWS IoT 프로비저닝은 디바이스를 안전하게 등록하고 관리하는 과정을 말합니다. 이 과정에서 CSR(Certificate Signing Request) 생성이 필요한데, 이는 디바이스의 신원을 인증하는 데 사용되는 중요한 요소입니다.

Bouncy Castle 소개

Bouncy Castle은 Java와 C# 기반의 경량 암호화 API입니다. 넓은 범위의 암호화 알고리즘을 지원하여 개발자들 사이에서 널리 사용되며, CSR 생성에도 유용합니다.

다음 장에서는 Bouncy Castle을 활용하여 CSR 생성 과정에 대해 자세히 설명드릴 예정입니다.

목차로 돌아가기

2장. Bouncy Castle을 이용한 CSR 생성 과정

Bouncy Castle을 이용하여 CSR을 생성하는 과정은 다음과 같습니다.

1. Bouncy Castle 라이브러리 설치

먼저, Bouncy Castle 라이브러리를 설치해야 합니다. Java 기반의 애플리케이션에서는 Maven repository에서 직접 다운로드 받을 수 있습니다.

2. 키 쌍 생성

Bouncy Castle API를 사용하여 RSA 키 쌍을 생성합니다. 이 키 쌍은 나중에 CSR 요청 시 사용됩니다.

3. CSR 요청 정보 작성

AWS IoT에 등록할 디바이스의 정보를 포함한 CSR 요청 정보를 작성합니다.

4. CSR 생성 및 서명

Bouncy Castle API를 사용하여 위에서 준비한 정보로 CSR을 생성하고, 개인키로 서명합니다.

위의 과정들은 AWS IoT 프로비저닝 과정 중 가장 중요한 단계입니다. 다음 장에서는 실제 예시를 통해 이해도를 높여보도록 하겠습니다.

목차로 돌아가기

3장. 실제 예시를 통한 CSR 생성 과정 이해

이번 장에서는 실제 코드 예시를 통해 Bouncy Castle을 이용한 CSR 생성 과정을 자세히 살펴보겠습니다.

1. Bouncy Castle 라이브러리 설치

Maven 프로젝트의 경우, pom.xml 파일에 다음과 같이 의존성을 추가합니다.

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.68</version>
    </dependency>
  

2. 키 쌍 생성

Bouncy Castle API를 사용하여 RSA 키 쌍을 생성하는 코드는 다음과 같습니다.

  KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
  keyPairGenerator.initialize(2048, new SecureRandom());
  KeyPair keyPair = keyPairGenerator.generateKeyPair();

3. CSR 요청 정보 작성

AWS IoT에 등록할 디바이스의 정보를 포함한 CSR 요청 정보를 작성하는 코드는 다음과 같습니다.

X500Name subject = new X500Name("CN=Your Device,O=Your Organization,L=Your City,C=Your Country");

4. CSR 생성 및 서명

Bouncy Castle API를 사용하여 위에서 준비한 정보로 CSR을 생성하고, 개인키로 서명하는 코드는 다음과 같습니다.

PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
ContentSigner signer = csBuilder.build(keyPair.getPrivate());
PKCS10CertificationRequest csr = p10Builder.build(signer);
  

AWS IoT 프로비저닝 과정 중 Bouncy Castle을 활용하여 CSR을 생성하는 방법에 대해 상세하게 알아보았습니다. 마지막 장에서는 이 내용들에 대한 결론 및 요약을 진행하겠습니다.

목차로 돌아가기

4장. 결론 및 요약

AWS IoT 프로비저닝 과정 중 Bouncy Castle을 활용하여 CSR 생성하는 방법에 대해 알아보았습니다. AWS IoT 프로비저닝은 디바이스를 안전하게 등록하고 관리하는 과정이며, 이 과정에서 CSR(Certificate Signing Request) 생성이 필요합니다. Bouncy Castle API를 사용하여 CSR을 생성하고, 개인키로 서명할 수 있습니다.

우리는 실제 코드 예시를 통해 이 과정을 자세히 살펴보았습니다. 이를 통해 AWS IoT 프로비저닝과 Bouncy Castle의 활용에 대한 이해도가 높아졌기를 바랍니다.

목차로 돌아가기

Friday, June 9, 2023

AndroidでAWS SDKを使ってMQTT通信の実装

Android用AWS SDKを使用してIoTデバイスと通信する

Android用のAWS SDKでは、MQTTプロトコルを通じてIoTデバイスと通信することができます。MQTTは、パブリッシュ/サブスクライブモデルに基づく軽量なプロトコルであり、SDKではAWSIotMqttManagerクラスを介して実装されています。

トピックへのサブスクライブ

subscribeToTopic()メソッドは特定のトピックにサブスクライブし、公開されたメッセージのコールバックを登録するために使用できます。以下のKotlinコードはこのプロセスを示しています:


val topic = "your/topic"
val qos = 0

awsIotMqttManager.subscribeToTopic(topic, qos) { topic, message ->
    // メッセージが受信された時に処理します
    val msg = String(message.payload, Charset.forName("UTF-8"))
    Log.d("MQTT message received", ": $topic, Message: $msg")
}

エラーハンドリング:コールバックメソッドから切断する

サブスクリプションとコールバックが正常に機能していても、特定の理由から接続を閉じる必要がある場合があります。コールバック内からAWSIotMqttManagerのdisconnect()メソッドを呼び出すと次のエラーが発生します:

"コールバックメソッドから切断することは許可されていません (32107)"

Kotlin Coroutines on AndroidでCallback Issues解決する

この問題を解決するためには、Android上でKotlin のCoroutine 機能を利用します。Coroutines は非同期タスクを容易に実行し、マルチスレッディングを容易に扱う機能です。

Your Project内でCoroutines ライブラリ含める

callback issues を解決するためCoroutines を使用したい場合、まず kotlinx.coroutines ライブラリをプロジェクトに含めます。

CoroutineScope Object を使用して安全に接続を閉じる

callback内で CoroutineScope オブジェクトを作成し、それ内で AWSIotMqttManager 上のdisconnect() を呼び出します。これにより、callbackメソッド内から安全に接続を閉じてエラーを回避することが可能です。


// Subscribe to a topic and register a callback using subscribeToTopic()
val topic = "your/topic"
val qos = 0

awsIotMqttManager.subscribeToTopic(topic, qos) { topic, message ->
    // メッセージが受信された時に処理します
    val msg = String(message.payload, Charset.forName("UTF-8"))
    Log.d("MQTT message received", "Topic: $topic, Message: $msg")

    // 接続を閉じる処理(例えば、特定のメッセージが受信されたとき)
    CoroutineScope(Dispatchers.Default).launch {
        awsIotMqttManager.disconnect()
    }
}

結論

このようにコードを設定することで、コールバックメソッドから正常に接続を閉じることができます。これにより、「コールバックメソッドから切断することは許可されていません(32107)」のエラーが発生するのを防ぐことができます。

Implementing MQTT Communication with AWS SDK on Android

Communicating with IoT Devices using AWS SDK for Android

The AWS SDK for Android offers a way to communicate with IoT devices through the MQTT protocol. MQTT, a lightweight protocol based on the publish/subscribe model, is implemented in the SDK via the AWSIotMqttManager class.

Subscribing to Topics

The method subscribeToTopic() is used to subscribe to specific topics and register callbacks for published messages. The following Kotlin code illustrates this process:


val topic = "your/topic"
val qos = 0

awsIotMqttManager.subscribeToTopic(topic, qos) { topic, message ->
    // Process the message when it is received
    val msg = String(message.payload, Charset.forName("UTF-8"))
    Log.d("MQTT message received", ": $topic, Message: $msg")
}

Error Handling: Disconnecting from Callback Method

Even when subscription and callbacks are functioning correctly, there may be instances where you need to close the connection due to specific reasons. Attempting to call the disconnect() method of AWSIotMqttManager from within the callback will result in an error:

"Disconnecting from the callback method is not allowed (32107)"

Solving Callback Issues with Kotlin Coroutines on Android

To solve this issue, you can utilize Kotlin's Coroutine feature on Android. Coroutines enable easy execution of asynchronous tasks and facilitate multithreading.

Including Coroutines Library in Your Project

To use coroutines for solving callback issues, first include kotlinx.coroutines library in your project.

Safely Closing Connection Using CoroutineScope Object

Create a CoroutineScope object within your callback and call disconnect() on AWSIotMqttManager within it. This allows you safely close connection from within your callback method and avoid errors.


import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

// ...

// Subscribe to a topic and register a callback using subscribeToTopic()
val topic = "your/topic"
val qos = 0

awsIotMqttManager.subscribeToTopic(topic, qos) { topic, message ->
    // Process the message when it is received
    val msg = String(message.payload, Charset.forName("UTF-8"))
    Log.d("MQTT message received", "Topic: $topic, Message: $msg")

    // Handle connection closure (for example, when a specific message is received)
    CoroutineScope(Dispatchers.Default).launch {
        awsIotMqttManager.disconnect()
    }
}

Conclusion

By configuring your code in this way, you can safely close the connection from within the callback method. This prevents the error "Disconnecting from the callback method is not allowed (32107)" from occurring.

Android에서 AWS SDK와 Coroutine을 활용한 MQTT 통신 구현

Android에서 AWS SDK와 MQTT를 이용한 IoT 통신

Android 개발에서 AWS SDK를 활용하면, IoT 기기와의 소통을 위해 MQTT 프로토콜을 사용할 수 있습니다. MQTT는 메시지 발행과 구독을 중심으로 하는 경량 프로토콜입니다. 이러한 특성들을 구현하기 위해, AWS SDK는 AWSIotMqttManager 클래스를 제공합니다.

subscribeToTopic 메소드를 통한 메시지 구독 및 콜백 등록

subscribeToTopic 메소드를 사용하면, 우리는 특정 주제(topic)에 대해 구독할 수 있으며, 동시에 발행되는 메시지에 대한 콜백도 등록할 수 있습니다. 아래 Kotlin 코드 예제에서 확인해볼 수 있습니다.


val topic = "your/topic"
val qos = 0

awsIotMqttManager.subscribeToTopic(topic, qos) { topic, message ->
    // 여기서 받은 메시지 처리
    val msg = String(message.payload, Charset.forName("UTF-8"))
    Log.d("MQTT message received", ": $topic, Message: $msg")
}

AWSIotMqttManager의 disconnect()메소드 오류 해결 방법

구독과 콜백이 정상적으로 진행되더라도 일부 경우에서 연결 종료가 필요할 때가 있습니다. 그런데 이럴 때 콜백 내부에서 AWSIotMqttManager의 disconnect() 메소드를 호출하려고 하면 아래와 같은 에러가 발생합니다:

"콜백 메소드로부터 연결을 끊는 것이 허용되지 않음 (32107)"

Kotlin 언어의 Coroutine 기능을 활용하여 이 문제를 해결하는 방법이 있습니다. Coroutine은 비동기 작업을 간단하게 처리하는 기능으로 멀티스레딩 작업에 유용합니다.

kotlinx.coroutines 라이브러리 추가 및 CoroutineScope 객체 생성

kotlinx.coroutines 라이브러리를 프로젝트에 포함시킨 후 콜백 내부에서 CoroutineScope 객체를 생성하고 그 안에서 AWSIotMqttManager의 disconnect()를 호출합니다. 이렇게 하면 콜백 메소드 내에서도 안전하게 연결을 종료하고 에러를 방지할 수 있습니다.

예제 코드


import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

// ...

val topic = "your/topic"
val qos = 0

awsIotMqttManager.subscribeToTopic(topic, qos) { topic, message ->
    // 여기서 받은 메시지 처리
    val msg = String(message.payload, Charset.forName("UTF-8"))
    Log.d("MQTT message received", ": $topic, Message: $msg")

    // 연결 종료 처리 (예: 특정 메시지를 받았을 때)
    CoroutineScope(Dispatchers.Default).launch {
        awsIotMqttManager.disconnect()
    }
}

결론

위와 같이 코드를 구성하면, 콜백 메소드 내에서도 안전하게 연결을 종료할 수 있습니다. 이는 "콜백 메소드로부터 연결을 끊는 것이 허용되지 않음 (32107)" 같은 에러를 방지하는데 큰 도움이 됩니다.

Tuesday, May 30, 2023

AWS EC2へのSSH接続時の許可エラー発生の問題と解決方法

AWS EC2へのSSH接続時に許可エラーが発生する問題とその解決方法

AWS EC2へSSHで接続しようとした際に、「許可エラー」が表示されることがあります。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'xxx.pem' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: xxx.pem
Permission denied (publickey).

AWS EC2のpemファイルの許可設定エラー

このエラーは、AWS EC2のpemファイルの許可が適切に設定されていない場合に発生します。以下に、pemファイルの許可を変更する手順を説明します。

pemファイルの許可を変更する方法

  1. まず、ターミナルを開きます。
  2. 次に、pemファイルが保存されているディレクトリに移動します。
  3. そして、以下のコマンドを入力し実行します:chmod 400 xxx.pem
  4. 最後に、再度SSHでAWS EC2へ接続してみてください。

AWS EC2へのSSH接続エラー解消

以上の手順で、許可エラーは解消されるはずです。これで無事にAWS EC2へ接続することが可能となります。

Monday, May 8, 2023

Solving Permission Errors During AWS EC2 SSH Connection

Solving Permission Errors During AWS EC2 SSH Connection

Dealing with permission errors while attempting to connect to AWS EC2 through SSH can be vexing. This guide will help you understand these common errors and provide effective solutions.

Deciphering the Error Messages

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!      @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'xxx.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: xxx.pem
Permission denied (publickey).

The error messages displayed above usually arise when the permissions for your PEM file in AWS EC2 are incorrectly set. The system flags the file as being excessively accessible, which poses a security risk.

Quick Resolution: Altering PEM File Permissions

By following these simple steps, you can modify the permissions on your PEM file:

  1. Open a terminal and navigate to the location of your PEM file.
  2. Enter and execute the following command:
  3. chmod 400 xxx.pem
  4. After running this command, try reconnecting to AWS EC2 via SSH.

By following this process, any permission errors should be resolved, enabling a smooth connection to AWS EC2 through SSH.

Monday, February 8, 2021

AWS EC2에서 Out of Memory 문제 해결 방법

AWS EC2 인스턴스에서의 메모리 문제 해결 방법

AWS의 EC2 인스턴스를 사용하면서 Spring Boot와 MySQL로 서비스를 배포하다가 서버 다운 문제에 직면하셨나요? 이 글에서는 그런 문제를 어떻게 해결했는지 공유드리겠습니다.

문제 상황

매일 한 번씩 서버가 다운되었습니다. 처음에는 로그 관리를 하지 않아 원인을 알 수 없었습니다.

AWS 콘솔에서의 문제 확인

AWS 콘솔의 EC2 항목에서 Monitor and Troubleshoot 기능을 이용하여 확인해 보니, 익숙한 메시지를 발견했습니다. OOM(Out of Memory)와 관련된 문제였습니다. 프리티어에서 제공하는 메모리가 1GB밖에 없어서 발생하는 것으로, 스왑 메모리 설정이 필요함을 알게 되었습니다.

aws console EC2
aws console EC2

문제 해결 방법

먼저 관리자 계정으로 로그인합니다.(EC2 관리자 계정 비밀번호를 설정하지 않았다면, 최초 설정 후 로그인이 가능합니다.) 그 후 아래 명령어들을 실행하여 스왑 메모리를 설정합니다:

root# dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048
root# sudo mkswap /mnt/swapfile
root# swapon /mnt/swapfile

free 명령어로 스왑 메모리가 설정되었는지 확인할 수 있습니다.

결과 확인

제대로 설정되었다면, 서버가 정상으로 구동되는 것을 확인할 수 있습니다. 이전에 비슷한 문제를 경험하셨다면, 같은 원인 때문이 아닐까 추정됩니다.

참고:

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/

Tuesday, January 26, 2021

10초만에 AWS Ubuntu EC2에서 Springboot .jar 파일을 자동 실행 서비스로 등록하는 방법

이 글은 AWS EC2에서 우분투 20.04를 사용하며, 서버가 자주 중단되어 자동 재시작을 설정해야 하는 상황에 대한 해결 방법을 소개합니다. 복잡한 과정 없이 간단하게 .sh 파일 없이 바로 적용 가능한 방법을 제공합니다.

server_start.service 파일 생성

/etc/systemd/ 경로에 server_start.service 파일을 만들고 다음과 같이 작성합니다:

[Unit]
Description=server start
After=mysql.service

[Service]
ExecStart=/bin/bash -c "exec java -jar /home/ubuntu/my-0.0.1-SNAPSHOT.jar"

[Install]
WantedBy=multi-user.target

ExecStart=/bin/bash -c "exec java -jar /home/ubuntu/my-0.0.1-SNAPSHOT.jar" 부분은 서비스가 실행될 때 바로 명령어가 실행되도록 설정하는 핵심입니다.

서비스 동작 확인

작성한 서비스가 잘 동작하는지 다음 명령어를 통해 확인할 수 있습니다:

sudo systemctl daemon-reload
sudo systemctl start server_start.service
sudo systemctl status server_start.service

재부팅 후 정상 작동 확인

재부팅 후에도 정상 작동하는지 확인하려면 sudo reboot 명령어로 재부팅한 후에 .jar 프로세스가 실행 중인지 확인하면 됩니다.

Wednesday, June 10, 2020

Flutter에서 AWS S3로 파일 업로드 Presigned URL과 Lambda Cold Start 문제 해결

Flutter에서 AWS S3로 파일 업로드: Pre-signed URL과 Lambda Cold Start 문제 해결

이 글에서는 Flutter에서 AWS S3로 파일을 직접 업로드하는 방법 및 Lambda Cold Start 문제 해결에 대해 설명합니다.

기존의 방식과 문제점

기존에는 앱에서 서버를 거쳐 S3로 파일을 업로드하는 방식을 사용하였습니다. 이 방식은 비효율적이므로, 앱에서 직접 S3로 파일을 업로드하는 방식을 도입하였습니다. 하지만 Flutter에서는 아직 AWS SDK가 제공되지 않아, 서버에서 Presigned URL을 받아야 했습니다.

우리 서비스는 Serverless를 지향하고 있어서 이 기능도 Lambda에 구현하였습니다. SDK를 활용해 URL을 생성 후 내려주고 테스트해보니 잘 동작하였으나, 예상치 못한 문제가 발생하였습니다.

Lambda Cold Start 문제 발생

일정 시간 동안 사용하지 않다가 Presigned URL을 담당하는 Lambda 함수를 다시 호출하면, 기존과 다른 URL을 반환하는 문제가 발생하였습니다. 이로 인해 파일 업로드가 정상적으로 이루어지지 않았습니다.

임시방편 해결방법

임시방편으로 최초 요청은 더미 요청으로 처리하고, 2번째 요청부터 반환된 URL을 사용하도록 하였습니다. 하지만 이 방법이 올바른 해결 방법인지에 대한 확신은 없었습니다.

Lambda Cold Start 문제 해결

구글링 결과 람다의 Cold Start 문제일 수 있다는 정보를 얻었습니다. 이를 해결하기 위해, 아래와 같은 IAM 정책을 Lambda 함수에 추가하였습니다:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::버킷명",
                "arn:aws:s3:::버킷명/*"
            ]
        }
    ]
}

이렇게 함으로써 Lambda Cold Start 문제를 해결할 수 있었습니다.

Thursday, December 26, 2019

AWS API Gateway와 Lambda를 이용한 Multipart 데이터 업로드 문제 해결

AWS API Gateway와 Lambda를 이용한 Multipart 데이터 업로드 문제 해결

AWS API Gateway와 Lambda(Node.js)를 사용하여 multipart 데이터를 업로드하는 방법에 대해 여러가지 방식을 찾아보았습니다. 제가 이전에 작성한 내용이 있으니 아래 링크를 참고하시면 도움이 될 것입니다.

AWS API Gateway + Lambda Multipart/Form-data

그런데 위에서 설명한 방식으로 설정을 하니, 일반 텍스트 필드와 이미지 파일이 함께 업로드되면 오류가 발생했습니다. 설정이나 전송 과정에서 문제가 있는 줄 알고 몇일 동안 고민하며 다양한 테스트를 진행했지만, 해결하지 못했습니다.

결국 사용하던 'parse-multipart' 패키지의 내용을 확인해보니, 해당 패키지는 파일만 지원하는 것이었습니다. 따라서 다른 패키지인 lambda-multipart-parser를 사용하여 다시 구성하기로 결정했습니다.

Lambda multipart upload example
Lambda에서의 multipart 데이터 업로드 예시

다만 대부분의 예제들은 API Gateway에서 Lambda proxy를 사용하는 경우였습니다. 그래서 Proxy를 사용하지 않는 제 경우처럼 구성해야 하는 분들을 위해 간략하게 구성 방법을 설명합니다. 우선, API Gateway 설정은 위 링크대로 하시면 되고, Lambda에서는 위 이미지와 같이 작성하면 됩니다.

Wednesday, July 3, 2019

G Suite 사용 중 이메일 수신 문제 해결: AWS Route53 MX Records 설정

G Suite 사용 중에 갑자기 이메일이 받아지는 문제가 발생했습니다.

문제 원인: MX Records 설정 누락

원인은 기존 사이트 도메인을 AWS Route53으로 옮겨놓고 MX records를 설정하지 않아서였습니다. 네트워크 전문가도 아니고 경험도 없는데다가 옮긴지 2~3일 후 부터 메일이 오지 않아서 원인을 찾는데 오래 걸렸습니다.

AWS Route53에서 MX Records 설정하기

AWS Route53에서 아래의 값들을 간단히 설정해주면 해결됩니다.

G Suite MX records screenshot

G Suite MX records

우선 route에서 'Create Record Set'을 선택한 뒤,

Selecting MX in AWS Route 53 screenshot

Selecting MX in AWS Route 53

MX를 선택한 후 아래와 같이 입력해주면 됩니다 (앞부분에 우선순위).

Setting MX records in AWS Route 53 screenshot

TTL 설정하기

TTL의 경우는 1시간이라는 곳도 있고 24시간이란곳도 있는데 알아서 선택하면 됩니다.

Saturday, May 11, 2019

AWS Lambda와 API Gateway 활용, S3에 Multipart 이미지 업로드 시 파일 깨짐 문제 해결

AWS API Gateway와 Lambda
AWS API Gateway와 Lambda

서비스 개발 중에 클라이언트에서 multipart로 사진을 AWS Lambda로 보내고, Lambda에서 S3로 다시 사진을 업로드하는 작업이 필요했습니다. Flutter를 이용해 서비스를 개발하려 했으나 아직 Flutter용(dart) SDK가 없어서 우리쪽 서버를 거쳐서 보내기로 결정했습니다.

미디어 타입 설정

Lambda 코드 작성 전에 API gateway에서 미디어 타입을 추가해야 합니다.

API Gateway 미디어 타입 설정
API Gateway에서 미디어 타입 설정하기

코드 작성 및 팁 공유

인터넷에서 여러 자료를 참고하여 아래와 같은 코드를 작성했습니다. 이 예제는 여러 장의 사진을 받아 1장만 S3로 업로드하는 방법입니다. 한 가지 팁으로는, AWS SDK가 이미 설치되어 있으므로 별도의 설치가 필요하지 않다는 점입니다.


//const AWS = require('aws-sdk');
const multipart = require('parse-multipart');
exports.handler = (event, context, callback) => {
    const s3 = new AWS.S3({
        credentials: {
            accessKeyId: 'your accessKeyId',
            secretAccessKey: 'your secretAccessKey',
        },
        params: { Bucket: 'your Bucket' }
    });

    let bodyBuffer = Buffer.from(event['body-json'], 'base64');
    let boundary = multipart.getBoundary(event.params.header['content-type']);
    let parts = multipart.Parse(bodyBuffer, boundary);
    let data = {
        Key: 'your path',
        Body: parts[0].data,
        ContentEncoding: 'base64',
        ContentType: 'image/jpeg'
    };

    s3.putObject(data, function (err, data) {
      if (err) {
          callback(null, err);
      } else {
          callback(null, data);
      }
   });
};

테스트 및 문제 해결


<html>
<body>
<form action="https://your-url" enctype="multipart/form-data" method="post">
    <input multiple="" name="body-json" type="file" />
    <input type="submit" value="Submit" />
</form>
</body>
</html>

위와 같이 웹페이지를 만들어 테스트를 진행했지만 어떤 때는 동작하고 어떤 때는 동작하지 않는 이상한 상황이 발생했습니다. 원인을 찾기 위해 여러 가지 시도를 해봤지만 결국 문제의 원인은 웹에서 보낼 때 캐릭터셋 지정이 없어서 한글 파일의 경우 파일명이 깨지고 전송 후에 파일 자체가 깨지는 것이었습니다. 이를 해결하기위해 form 태그 안에 accept-charset="UTF-8"속성을 추가하고 다시 테스트해 보니 문제가 해결되었고, S3 업로드도 잘 실행되었습니다.


<html>
<body>
<form action="https://your-url" enctype="multipart/form-data" method="post" accept-charset="UTF-8">
    <input multiple="" name="body-json" type="file" />
    <input type="submit" value="Submit" />
</form>
</body>
</html>

사실상 코드는 큰 문제가 없었는데 캐릭터셋을 생각하지 못하고 코드 문제인 줄 알아서 이것저것 시도하느라 시간을 많이 잡아먹었습니다. 혹시 같은 작업이나 비슷한 문제를 겪는 사람들에게 조금이라도 도움이 되길 바랍니다.

참고 : 여러 형식의 파일 multipart upload 방법(https://blogdeveloperspot.blogspot.com/2019/12/aws-apigateway-lambdanodejs-multipart.html)

Friday, April 26, 2019

AWS S3와 Route53을 활용한 정적 웹페이지 호스팅 문제 해결

AWS에서 S3와 Route53을 이용한 정적 웹페이지 설정

Amazon Web Services(AWS)의 S3는 html, javascript, css 등의 파일을 저장하고 제공할 수 있는 서비스입니다. 이를 이용해 정적 웹페이지(static web page)를 만들고, Route53을 통해 도메인을 설정할 수 있습니다. 그러나 때때로 Route53에서 ALIAS 설정 시 S3 버킷이 목록에 보이지 않는 문제가 발생합니다.

S3 버킷 이름과 도메인 이름 일치 여부 확인

이런 문제가 발생할 경우 첫 번째로 확인해야 할 것은 생성한 S3 버킷의 이름과 연결하려는 도메인 이름이 일치하는지 여부입니다. 예를 들어, 'example.com'이라는 도메인으로 연결하려면, 해당하는 S3 버킷의 이름도 반드시 'example.com'으로 설정되어 있어야 합니다.

AWS 사용 팁: 초기 설정 주의 사항

위 내용은 간단하지만 AWS를 처음 사용하는 사람들에게는 알기 어려운 부분일 수 있습니다. 따라서 이 정보가 AWS 서비스를 처음 접하는 사람들에게 유익하길 바라며, 이러한 팁을 공유함으로써 불필요한 시간 낭비를 줄일 수 있기를 기대합니다.

Thursday, January 31, 2019

AWS EC2에서 SSH 접속 오류 REMOTE HOST IDENTIFICATION HAS CHANGED 해결법

EC2에서 'REMOTE HOST IDENTIFICATION HAS CHANGED' 오류 해결 방법

Amazon EC2 인스턴스에 pem 파일을 사용하여 키를 설정하고 접속하려는데, 'REMOTE HOST IDENTIFICATION HAS CHANGED!'라는 오류 메시지와 함께 접속이 안되는 문제가 발생했습니다. 이 문제의 원인은 기존에 사용하던 IP 주소를 그대로 유지하면서 EC2 인스턴스만 변경했기 때문에 SSH에 저장된 IP와 pem 키의 쌍이 일치하지 않아 발생한 것입니다.

이런 문제를 해결하는 방법은 사실 매우 간단합니다. 아래의 명령어를 한 번만 실행하고 다시 접속하면 쉽게 해결할 수 있습니다:

ssh-keygen -R <사용 중이던 ip주소>

Saturday, January 5, 2019

Javascript에서 AWS S3 파일 업로드 시 URL 인코딩 문제 해결하기

Javascript와 AWS S3를 활용한 파일 업로드: URL 인코딩 문제 해결

이 글에서는 AWS S3와 JavaScript를 사용하여 파일을 업로드할 때 발생하는 URL 인코딩 문제에 대한 해결 방법을 제시합니다. 이는 JavaScript의 일반적인 문제로, 다른 컨텍스트에서도 적용될 수 있습니다.

문제 상황 정의

Javascript를 사용하여 AWS S3로 파일을 업로드할 때, 특히 multipart upload를 사용하면, 반환되는 data.Location 값이 한글일 경우 URL 인코딩되어 반환됩니다. 이러한 현상은 아래 이미지와 같습니다.

URL 인코딩 예시
URL 인코딩 결과 예시

해결 방법 탐색과 적용

's3 url decoding' 등의 키워드로 검색해도 명확한 해결법을 찾기 어려웠습니다. 하지만, 결국 Javascript 자체에서 제공하는 URL 디코딩 함수(decodeURI())가 있다는 것을 알게 되었습니다.

W3Schools의 decodeURI() 함수 설명에 따르면, 이 함수는 주어진 URI에서 특수 문자들을 UTF-8 형식으로 디코드합니다.

디코딩 결과
decodeURI() 함수 적용 결과

결과와 회고

decodeURI() 함수를 적용한 결과, URL 인코딩 문제는 성공적으로 해결되었습니다. 이 문제 해결 과정은 단순했지만, 그에 걸린 시간은 상당했습니다. 이 경험을 통해 JavaScript에서 제공하는 기본 함수의 중요성을 다시 한번 깨닫게 되었습니다.

Thursday, December 27, 2018

AWS Lambda에서 Node.js에 Firebase 패키지 설치 문제 해결 방법

AWS Lambda에서 Node.js에 Firebase 패키지 설치 문제 해결 방법

AWS Lambda에서 Node.js 환경으로 설정하고 Firebase 패키지를 사용하는 과정에서 문제가 발생하는 경우가 있습니다. 이 문제를 해결하기 위한 방법을 알아보겠습니다.

문제 상황

AWS Lambda에 Node.js 8.10 환경으로 세팅하고 여러 패키지를 zip 파일로 업로드하는 중에 Firebase 패키지 설치에 문제가 발생합니다. 구글링 결과, 대부분의 경우 'npm rebuild' 명령어를 사용하여 해결할 수 있다고 언급하지만, 해당 방법으로는 문제가 해결되지 않았습니다.

https://github.com/grpc/grpc-node/issues/121 링크에서 확인한 바에 따르면, 버전 호환성 문제일 수 있습니다. 따라서 Firebase 패키지의 버전을 명시적으로 지정하여 설치해야 합니다. 현재 설치된 Node.js 버전은 8.10입니다.

해결 방법

위 링크에서 제시된 내용을 참고하여 npm을 사용하여 firebase@4.12.1 버전을 명시적으로 설치하면 문제가 해결됩니다. 아마도 Node.js와 Firebase 패키지 간의 버전 호환성 문제일 것입니다. 비슷한 문제를 겪는 사람들은 버전을 체크해보는 것이 좋습니다.

Tuesday, November 6, 2018

AWS에 spring과 mysql 환경 구축시 서버가 자꾸 느려지거나 꺼질 경우

AWS 프리티어 사용 시 서버 성능 저하 문제와 DB 연결 관리

AWS 프리티어를 사용하여 개발 서버를 운영하다가 어느 순간부터 서버의 응답 속도가 느려져서 재부팅을 해야하는 상황이 발생한 경험에 대해 이야기해보겠습니다.

문제 상황

처음에는 AWS 프리티어의 특성상 성능이 떨어지거나, 사용량 제한을 초과해서 그런 것으로 생각했습니다. 하지만, 데이터베이스를 RDS로 옮긴 후에는 서버가 다운되거나 응답 속도가 느려지는 현상이 확연하게 줄었습니다.

원인 분석

원인을 추측해보면, 데이터베이스 연결(DB connection)을 열고 닫는 코드가 없어서 발생한 문제 같습니다. 이로 인해 데이터베이스 연결 자원이 과도하게 소모되었고, 이로 인해 서버 성능 저하 현상이 발생한 것으로 보입니다.

DB Connection 관리 중요성

데이터베이스 연결은 한정된 자원입니다. 따라서 필요할 때만 열고, 작업 완료 후에는 반드시 닫아주는 것은 매우 중요합니다. 이를 통해 자원의 효율적인 활용과 함께 시스템의 안정성을 유지할 수 있습니다.

조언

AWS에서 개발서버를 운영하면서 갑자기 서버 응답 속도가 느려진다면 DB connection 관리 상태를 확인하는 것도 하나의 해결 방안일 수 있습니다.

Wednesday, September 12, 2018

점진적 AWS 도입과정 경험담

AWS 서비스 아키텍처 재구성: AWS, EC2, S3, RDS, Lambda

사진을 올리고 거래하는 장터 어플의 서버를 물려받게 되었습니다. 처음에는 AWS를 사용하는 EC2 인스턴스 하나에 tomcat, mysql, spring을 이용한 웹과 API 서버가 한데 어울려져 있었습니다. 이 상황에서 AWS 아키텍처를 새롭게 구성해보기로 결정하였습니다.

1단계: S3 도입 - 파일 저장 문제 해결

우선 사진이 상당히 많이 올라가게 되는데 이것을 EC2 인스턴스 볼륨에 저장하고 있었습니다. 이로써 발생한 문제를 해결하기 위해 외부 저장소인 s3를 도입하여 파일을 바로 s3로 저장할 수 있도록 수정하였습니다.

2단계: RDS 도입 - 데이터베이스 안정화

그 다음으로 mysql 서비스와 톰캣이 함께 종료되는 문제가 발생하였습니다. 이 문제를 해결하기 위해 RDS도 도입하여 데이터베이스 관리 부분을 분리하였습니다.

현재 아키텍처 구성: EC2 instance + S3 + RDS

3단계: Lambda와 API Gateway 도입 - API 관리 강화

다음 단계에서는 API서버와 웹서버의 분리가 필요해 보였습니다. 따라서 모든 API는 람다로 옮기고 ec2에는 웹서버만 남겼습니다.

현재 아키텍처 구성 : EC2 instance + S3 + RDS + Lambda(+API gateway)

4단계 : 로드 밸런싱 적용 – auto scale 및 분산 처리 강화

마지막으로 사용자가 늘어난 만큼 auto scale 및 분산 처리의 필요성이 느껴져 로드 벨런싱을 고려하기 시작했습니다. 여기서는 NLB와 ALB 중에서 선택해야 했으며, 이를 위해 다양한 정보를 수집하였습니다.

이 과정에서 매우 유용한 자료를 발견했습니다. 바로 AWS 공식 사이트의 아키텍처 섹션인 https://aws.amazon.com/architecture/ 입니다. 이곳에는 AWS 아키텍처에 대해서 매우 알아보기 쉽고 best case들을 소개하고 있습니다.

결론

지금까지 서비스의 아키텍처를 단계별로 재구성하는 과정을 소개하였습니다. 이제는 위의 예시를 기준으로 서비스를 더 발전시켜 볼 계획입니다.

Friday, September 7, 2018

AWS RDS에서 한글이 ???등으로 깨질 경우 대처법

AWS RDS에서 한글이 깨질 경우 해결방법

AWS RDS를 사용하다보면 한글이 ???로 깨지는 현상을 경험할 수 있습니다. 이러한 문제를 해결하기 위한 방법에 대해 알아봅시다.

AWS RDS 설정 이미지

character-set 설정

대부분의 경우, 파라미터 그룹에서 character-set을 utf8로 설정하면 이 문제가 해결됩니다. 하지만 일부 경우에는 이렇게 설정해도 문제가 계속 발생할 수 있습니다.

character-set-client-handshake 설정

문제가 계속되는 경우, character-set-client-handshake 값을 0으로 바꾸면 정상적으로 적용됩니다. 변경 후에는 반드시 RDS를 재부팅해야 합니다.

참고사항

MySQL 기준으로 이모티콘 설정을 위해서는 utf8mb4를 사용하는 것이 좋습니다.

출처: http://kkotkkio.tistory.com/98 [KKOTKKIO'S CAVE]