database "postgres", no encryption
AWS의 RDS에 postgres DB를 생성하고 연결하게 되면 이러한 에러가 발생한다.
이유는 암호화된 연결을 사용하지 않아서 이고, 간단하게 해결하고 싶다면 (NestJS 기준) DB설정 코드에
ssl: {
rejectUnauthorized: false,
},
를 추가하면 되긴한다.
하지만 이는 보안상 권장되지 않으니 배포 테스트 같은 경우에 사용하도록 하자.
그리고 권장 사항은 SSL 인증서를 사용하는 것이다.
SSL 인증서라고 하니깐 뭔가 복잡할 것 같은데 생각보다 간단하다.
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html
Using SSL/TLS to encrypt a connection to a DB instance or cluster - Amazon Relational Database Service
Using SSL/TLS to encrypt a connection to a DB instance or cluster You can use Secure Socket Layer (SSL) or Transport Layer Security (TLS) from your application to encrypt a connection to a database running Db2, MariaDB, Microsoft SQL Server, MySQL, Oracle,
docs.aws.amazon.com
위 페이지의 맨 밑에쯤에 보면 AWS 지역에 대한 인증서 번들을 다운로드할 수 있다. 자신의 RDS를 생성한 지역에 해당되는 번들을 받자.
내 경우에는 아시아 태평양(서울)의 인증서 번들(PEM)을 받았다.
내 경우 EC2를 생성할 때 받은 pem을 이용해 EC2에 접속한다.
보통 EC2에 ssl을 저장할 디렉토리가 이미 있긴하지만 혹시 모르니 생성하자.
sudo mkdir -p /etc/ssl/certs
EC2에 ssl 저장할 디렉토리 생성
scp -i /path/to/your-key.pem /local/path/to/ap-northeast-2-bundle.pem ec2-user@your-ec2-public-ip:~/
scp -i EC2접속키.pem SSL번들.pem EC2연결IP:EC2에 저장할 위치
순이다. 앞에 /로 된것들은 위치 경로들이다.
경로를 잘 모르겠거나 복잡하다면, 둘을 같은 폴더에 넣고 해당 폴더로 이동 후, 경로로 ./ 를 넣어주자.
그리고 앞서 다운받은 인증서 번들을 EC2로 복사한다.
EC2연결IP의 경우 ssh 접속할때 쓰던IP(퍼블릭 IPv4 DNS)를 적어줘야지 퍼블릭 IPv4를 적으면 거절당한다.
++ 앞에 사용자이름도 붙여줘야한다. ex) ubuntu@IPv4 DNS
그리고 바로 앞서 생성한 디렉토리로 바로 복사하는것도 권한 제한이 있을 수 있으니 일단 홈 디렉토리로 복사하자.
ls -l ap-northeast-2-bundle.pem
복사된 인증서 번들을 옮기기전에 권한 체크를 한번 해주자.
내 경우 rw-r--r-- 로 나왔는데, 첫번째는 파일 소유자, 두번째는 파일 소속 그룹, 세번쨰는 기타 사용자에 관한 권한으로, rw는 읽기쓰기 전부 가능하다.
sudo mv /home/ubuntu/ap-northeast-2-bundle.pem /etc/ssl/certs/
해당 명령어로 인증서 번들을 옮겼다면 db세팅의 코드를 변경해준다.
// database.config.ts
import * as fs from 'fs';
export const databaseConfig = {
useFactory: (configService: ConfigService): TypeOrmModuleOptions => {
const isProd = configService.get<string>(envKeys.env) === 'prod';
return {
type: configService.get<string>(envKeys.dbType) as 'postgres',
host: configService.get<string>(envKeys.dbHost),
port: configService.get<number>(envKeys.dbPort),
username: configService.get<string>(envKeys.dbUsername),
password: configService.get<string>(envKeys.dbPassword),
database: configService.get<string>(envKeys.dbDatabase),
autoLoadEntities: true, // 각각의 entity 일일이 입력 or 자동
synchronize: isProd ? false : true, // 스키마 동기화
logging: false, // 쿼리 실행 내역 터미널에 띄움
ssl: isProd
? {
ca: fs.readFileSync('/etc/ssl/certs/ap-northeast-2-bundle.pem'),
}
: false,
};
},
inject: [ConfigService],
};
내 경우 따로 파일을 만들어 db 설정코드를 작성해놓았기 때문에 위 코드와 같이 되어있다.
본인의 코드에 맞게 ssl 부분을 추가해주면 된다.
그리고 나는 Docker를 사용하고 있고, 코드의 간결함을 위해 docker-compose.yaml 파일도 EC2에 생성해두었다.
따라서 EC2의 docker-compose.yaml에 volumes을 추가해주어야한다.
services:
cmspp:
image: 이미지
volumes:
- /etc/ssl/certs/ap-northeast-2-bundle.pem:/etc/ssl/certs/ap-northeast-2-bundle.pem
ports:
- 포트
env_file:
- .env
이렇게 설정을 끝내고 서버를 실행하면 잘 동작한다.