* 의문 : WAS와 Redis간 통신보안의 best-practice?
- WAS와 Redis를 같은 VPC에 배치
- VPC 내부 통신만 허용
네, Redis 보안을 위한 Best Practice는 VPC 구성입니다. VPC를 통한 네트워크 격리가 가장 안전한 방법입니다.
flowchart TD
subgraph "Public Subnet"
ALB[Application Load Balancer]
end
subgraph "Private Subnet 1"
WAS1[WAS Instance 1]
WAS2[WAS Instance 2]
end
subgraph "Private Subnet 2"
Redis[(Redis)]
end
Internet[Internet] --> ALB
ALB --> WAS1
ALB --> WAS2
WAS1 --> Redis
WAS2 --> Redis
subgraph "Security Groups"
SG1[ALB SG<br>80, 443]
SG2[WAS SG<br>8080]
SG3[Redis SG<br>6379]
end
style Redis fill:#f96,stroke:#333,stroke-width:4px
style WAS1 fill:#99f,stroke:#333,stroke-width:2px
style WAS2 fill:#99f,stroke:#333,stroke-width:2px
AWS VPC 구성을 위한 Terraform 코드 예시:
/**
* Redis를 위한 VPC 및 보안 구성
* @description AWS VPC, 서브넷, 보안 그룹 설정
*/
# VPC 생성
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main"
Environment = "production"
}
}
# 프라이빗 서브넷 (Redis용)
resource "aws_subnet" "redis_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "redis-subnet"
}
}
# 프라이빗 서브넷 (WAS용)
resource "aws_subnet" "was_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "was-subnet"
}
}
# Redis 보안 그룹
resource "aws_security_group" "redis_sg" {
name = "redis-security-group"
description = "Security group for Redis"
vpc_id = aws_vpc.main.id
# WAS 서브넷에서만 Redis 포트 접근 허용
ingress {
from_port = 6379
to_port = 6379
protocol = "tcp"
security_groups = [aws_security_group.was_sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "redis-sg"
}
}
# WAS 보안 그룹
resource "aws_security_group" "was_sg" {
name = "was-security-group"
description = "Security group for WAS"
vpc_id = aws_vpc.main.id
# 로드밸런서에서만 WAS 포트 접근 허용
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.alb_sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "was-sg"
}
}
# VPC Endpoint 설정 (AWS 서비스 접근용)
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-northeast-2.s3"
}
Best Practice 세부 설명:
- 네트워크 격리:
network_isolation: vpc: - 전용 VPC 구성 - Private 서브넷 사용 - VPC Endpoint 활용 subnet: - Redis용 전용 서브넷 - WAS용 전용 서브넷 - 가용영역 분리
- 보안 그룹 설정:
security_groups: redis_sg: - WAS 보안그룹에서만 접근 허용 - 6379 포트만 개방 - 아웃바운드 제한 was_sg: - ALB에서만 접근 허용 - 필요한 포트만 개방
- 접근 제어:
access_control: network: - NACL 설정 - 라우팅 테이블 설정 - Flow Log 활성화 application: - IAM 역할 설정 - 암호화 통신
- 모니터링:
monitoring: - VPC Flow Logs - CloudWatch 설정 - AWS Config 규칙 - GuardDuty 활성화
이러한 VPC 기반 구성의 장점:
- 보안:
- 외부 접근 완전 차단
- 네트워크 수준 격리
- 세분화된 접근 제어
- 관리:
- 중앙화된 관리
- 자동화된 설정
- 감사 용이성
- 확장성:
- 유연한 리소스 확장
- 서브넷 추가 용이
- 멀티 AZ 구성 가능
주의사항:
- 비용 고려
- 복잡성 증가
- 초기 설정 시간 필요
추가 고려사항:
- 현재 어플리케이션의 규모는?
- 예상되는 트래픽 패턴은?
- 컴플라이언스 요구사항이 있나요?
이러한 정보를 추가로 알려주시면, 더 최적화된 VPC 구성을 제안드릴 수 있습니다.
* 의문2 : was, redis가 각각 공인 ip를 발급받아야 하는가?
아니요, 웹 서버를 제외한 나머지 서버들은 공인 IP가 필요하지 않습니다. 보안과 비용 측면에서 private 서브넷에 위치시키는 것이 Best Practice입니다.
flowchart TD
subgraph "VPC"
subgraph "Public Subnet"
Bastion[Bastion Host<br>공인 IP]
WebServer[Web Server<br>공인 IP]
end
subgraph "Private Subnet - Application Tier"
WAS[WAS Server<br>사설 IP]
end
subgraph "Private Subnet - Data Tier"
Redis[Redis Server<br>사설 IP]
end
end
Internet[Internet] --> Bastion
Internet --> WebServer
Bastion -.-> WAS
Bastion -.-> Redis
WebServer --> WAS
WAS --> Redis
style WebServer fill:#f96,stroke:#333,stroke-width:4px
style WAS fill:#99f,stroke:#333,stroke-width:2px
style Redis fill:#9f9,stroke:#333,stroke-width:2px
각 서버별 네트워크 구성을 코드로 보여드리겠습니다:
/**
* 클라우드 인프라 네트워크 구성
* @description AWS VPC, 서브넷, 라우팅 설정
*/
# VPC 설정
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
# 퍼블릭 서브넷 설정
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-2a"
tags = {
Name = "public-subnet"
}
}
# 프라이빗 서브넷 - 애플리케이션 계층
resource "aws_subnet" "private_app" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "private-subnet-app"
}
}
# 프라이빗 서브넷 - 데이터 계층
resource "aws_subnet" "private_data" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "private-subnet-data"
}
}
# 인터넷 게이트웨이
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"
}
}
# NAT 게이트웨이
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public.id
tags = {
Name = "main-nat"
}
}
# 탄력적 IP for NAT
resource "aws_eip" "nat" {
domain = "vpc"
}
# 퍼블릭 라우팅 테이블
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "public-rt"
}
}
# 프라이빗 라우팅 테이블
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main.id
}
tags = {
Name = "private-rt"
}
}
# 보안 그룹 설정
resource "aws_security_group" "bastion" {
name = "bastion-sg"
description = "Security group for Bastion host"
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["관리자 IP/32"]
}
}
resource "aws_security_group" "web" {
name = "web-sg"
description = "Security group for Web servers"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
각 서버 유형별 특징과 권장 사항:
- 공인 IP가 필요한 서버:
- 웹 서버 (또는 로드 밸런서)
- 외부 접근 필요
- HTTPS 통신
- 배스천 호스트
- 관리 접근용
- SSH 접근만 허용
- 공인 IP가 필요없는 서버:
- WAS 서버
- 내부 통신만 필요
- 보안 강화
- Redis 서버
- 데이터 보안
- 내부 접근만 허용
Best Practices:
- 네트워크 구성:
network_layout: public_subnet: - 웹 서버/로드밸런서 - 배스천 호스트 private_subnet: - WAS 서버 - Redis 서버 - 기타 내부 서비스
- 보안 설정:
security_config: public_instances: - 최소한의 포트만 개방 - WAF 적용 - DDoS 보호 private_instances: - 내부 통신만 허용 - VPC 내부 통신 - 보안그룹 체이닝
- 접근 관리:
access_management: bastion: - SSH 키 관리 - IP 화이트리스팅 - 세션 로깅 applications: - IAM 역할 사용 - 최소 권한 원칙
장점:
- 보안 강화
- 직접적인 외부 접근 차단
- 네트워크 격리
- 접근 통제 용이
- 비용 절감
- 공인 IP 비용 절감
- 트래픽 비용 최적화
- 관리 비용 감소
- 관리 용이성
- 중앙화된 접근 관리
- 단순화된 네트워크 구조
- 명확한 책임 분리
주의사항:
- NAT 게이트웨이 비용 고려
- 배스천 호스트 관리 필요
- 네트워크 구성 복잡성
추가 고려사항:
- 서버 관리 방식은 어떻게 되나요?
- CI/CD 파이프라인 구성이 필요한가요?
- 장애 복구 계획은 어떻게 되나요?
이러한 정보를 추가로 알려주시면, 더 최적화된 네트워크 구성을 제안드릴 수 있습니다.
* 배스천 호스트란?
배스천 호스트(Bastion Host)는 외부에서 private 서브넷의 리소스에 안전하게 접근하기 위한 중간 서버/게이트웨이입니다. 흔히 "점프 서버"라고도 부릅니다.
flowchart TD
Admin[관리자] -->|SSH| Bastion[Bastion Host<br>공인 IP<br>포트 22]
subgraph VPC[VPC]
subgraph "Public Subnet"
Bastion
end
subgraph "Private Subnet"
WAS[WAS Server<br>private IP]
Redis[Redis Server<br>private IP]
RDS[RDS<br>private IP]
end
end
Bastion -->|SSH| WAS
Bastion -->|SSH| Redis
Bastion -->|SSH| RDS
style Bastion fill:#f96,stroke:#333,stroke-width:4px
style WAS fill:#99f,stroke:#333,stroke-width:2px
style Redis fill:#99f,stroke:#333,stroke-width:2px
style RDS fill:#99f,stroke:#333,stroke-width:2px
배스천 호스트 구성을 위한 코드 예시:
/**
* 배스천 호스트 인프라 구성
* @description AWS 배스천 호스트 및 보안 설정
*/
# 배스천 호스트 보안 그룹
resource "aws_security_group" "bastion" {
name = "bastion-sg"
description = "Security group for Bastion Host"
vpc_id = aws_vpc.main.id
# SSH 접근 제한
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["관리자_IP/32"] # 특정 IP만 허용
}
# 아웃바운드 규칙
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "bastion-sg"
}
}
# 배스천 호스트 EC2 인스턴스
resource "aws_instance" "bastion" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
key_name = aws_key_pair.bastion.key_name
vpc_security_group_ids = [aws_security_group.bastion.id]
# 사용자 데이터 스크립트
user_data = <<-EOF
#!/bin/bash
# 보안 업데이트
yum update -y
# SSH 설정 강화
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# 감사 로깅 설정
echo "*.* @log-server:514" >> /etc/rsyslog.conf
# SSM Agent 설치
yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
systemctl enable amazon-ssm-agent
systemctl start amazon-ssm-agent
EOF
tags = {
Name = "bastion-host"
}
}
# SSH 키 페어
resource "aws_key_pair" "bastion" {
key_name = "bastion-key"
public_key = file("~/.ssh/id_rsa.pub")
}
# Systems Manager 역할
resource "aws_iam_role" "bastion" {
name = "bastion-ssm-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}
]
})
}
배스천 호스트 사용 방법:
- SSH config 설정:
# ~/.ssh/config Host bastion HostName {BASTION_PUBLIC_IP} User ec2-user IdentityFile ~/.ssh/bastion-key.pem
Host private-server
HostName {PRIVATE_IP}
User ec2-user
IdentityFile ~/.ssh/private-key.pem
ProxyCommand ssh bastion -W %h:%p
2. SSH 접속 명령어:
```bash
# 배스천 호스트 직접 접속
ssh bastion
# private 서버에 배스천 호스트를 통해 접속
ssh private-server
Best Practices:
- 보안 설정:
security_measures: network: - 특정 IP만 접근 허용 - 최소 포트만 개방 (22) - VPC 내부통신만 허용 system: - 정기적 패치 적용 - 루트 로그인 비활성화 - 키 기반 인증만 허용 monitoring: - 접속 로그 기록 - CloudWatch 경보 설정 - SSM 세션 관리
- 관리 방안:
management: access: - IAM 역할 사용 - MFA 적용 - 세션 타임아웃 설정 maintenance: - 자동 업데이트 - 백업 정책 - 장애 복구 계획
장점:
- 보안 강화
- 단일 접근 포인트
- 접근 로그 중앙화
- 인프라 보호
- 관리 용이성
- 중앙화된 접근 관리
- 간편한 감사
- 표준화된 접근 방식
- 비용 효율성
- 단일 공인 IP 사용
- 작은 인스턴스 사용 가능
- 관리 비용 절감
주의사항:
- 단일 실패 지점이 될 수 있음
- 정기적인 보안 업데이트 필요
- 접근 키 관리 중요
대안:
- AWS Systems Manager Session Manager
- AWS Direct Connect
- VPN 연결
추가 고려사항:
- 몇 명의 관리자가 접근하나요?
- 어떤 종류의 관리 작업이 필요한가요?
- 컴플라이언스 요구사항이 있나요?
이러한 정보를 추가로 알려주시면, 더 최적화된 배스천 호스트 구성을 제안드릴 수 있습니다.
'DevOps > Redis' 카테고리의 다른 글
24.11.6. 개발일지 // cloud에 redis 설치, private subnet (0) | 2024.11.07 |
---|