RDS 인스턴스에 public ip 를 사용하면 매달 5천원 ~ 1만원의 요금을 내야 한다
보안에서도 RDS 를 외부에 노출 시키지 않고 EC2 만 열어두어서 더 안전하다
AWS 설정
1. EC2 와 RDS 가 같은 리전에 있어야 한다.

( 같은 리전이라고 하면 오른쪽 위에 지역을 말한다.)
2. RDS 에 들어와서 오른쪽 작업 탭 -> EC2 연결 설정에 들어온다

3. 드롭다운을 눌러서 연결 시킬 EC2 를 선택해서 연결 시켜준다.

본격 진행
Jsch 라이러리 의존성 추가
// Jsch - SSH library
implementation ("com.github.mwiede:jsch:0.2.16")
application.properties ( Postgresql 사용 )
# 📦 DB Info
spring.datasource.url=jdbc:postgresql://localhost:[forwardedPort]/[데이터베이스이름]
# 🌐 SSH 터널링 호스트 주소 (예: EC2 퍼블릭 DNS)
ssh.tunnel.host=[ec2주소]
ssh.tunnel.port=22
ssh.tunnel.username=[ec2 user name: 기본 ubuntu]
ssh.tunnel.key=classpath:[.pem 키 경로]
rds.database_endpoint=[rds uri]
rds.database_port=[db port]
# 👤 인증 정보
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=[db user name]
spring.datasource.password=[db user password]
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:[forwardedPort]/[데이터베이스이름]
localhost 는 ec2 -> rds 로 접속하기 때문에 localhost 로 지정해준다.
SSH 로 연결 시켜줄 Config 를 작성 해준다.
@Profile("!test")
@Component
class SshCommandConfig(
@Value("\${ssh.tunnel.host}")
private val sshHost: String,
@Value("\${ssh.tunnel.port}")
private val sshPort: Int,
@Value("\${ssh.tunnel.username}")
private val sshUser: String,
@Value("\${ssh.tunnel.key}")
private val sshKeyPath: String,
@Value("\${rds.database_endpoint}")
private val dbEndpoint: String,
@Value("\${rds.database_port}")
private val dbPort: String,
) {
lateinit var session: Session
@PreDestroy
fun destroy() {
if (session.isConnected) {
session.disconnect()
}
}
@Bean
fun sshSession(): Int {
try{
val classPathResource = ClassPathResource(sshKeyPath)
if (!classPathResource.exists()) {
throw FileNotFoundException("❌ 리소스가 classpath에 존재하지 않음: aws/was_key.pem")
}
val tempKeyFile = File.createTempFile("temp-key", ".pem").apply {
outputStream().use { classPathResource.inputStream.copyTo(it) }
deleteOnExit() // JVM 종료 시 자동 삭제
}
val jsch = JSch()
jsch.addIdentity(tempKeyFile.absolutePath)
val session = jsch.getSession(sshUser, sshHost, sshPort)
val config = Properties()
config["StrictHostKeyChecking"] = "no"
session.setConfig(config)
session.connect()
val port = session.setPortForwardingL(0, dbEndpoint, Integer.parseInt(dbPort))
return port
}catch (ex: Exception){
throw RuntimeException("Failed to create SSH session", ex)
}
}
}
jsch.addIdentity(tempKeyFile.absolutePath)
이 부분에서 keyPath 를 넣어줘야 하는데 키 패스가 안읽혀서 임의의 파일을 생성해주고 주소를 넣는 방식으로 했다.
@Profile("!test")
@Component
class SshDataSourceConfig(
private val initializer: SshCommandConfig
) {
@Bean("dataSource")
@Primary
fun dataSource(properties: DataSourceProperties): DataSource {
val forwardedPort = initializer.sshSession()
val url = properties.url.replace("[forwardedPort]", forwardedPort.toString())
return DataSourceBuilder.create()
.url(url)
.username(properties.username)
.password(properties.password)
.driverClassName(properties.driverClassName)
.build()
}
}
SSH 로 접속이 완료 되었다면,
val forwardedPort = initializer.sshSession()
포워딩 시킨 포트로 db를 접속이 된다.

'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
[Spring] NCP SMS 인증번호 시스템 구현 (1) | 2024.12.03 |
---|---|
[Spring] ServletRequest 캐싱 (ContentCachingRequestWrapper) (0) | 2024.12.02 |
[Spring] 상대방 채팅 읽음 감지 (1) | 2024.11.17 |
[spring] Cache 조회 성능을 최적화 Redis + Kotlin (0) | 2024.11.14 |
[WebSoket] Spring + SocketJs 사용하기 ( 테스트 Html코드 공유 ) (0) | 2024.11.02 |
RDS 인스턴스에 public ip 를 사용하면 매달 5천원 ~ 1만원의 요금을 내야 한다
보안에서도 RDS 를 외부에 노출 시키지 않고 EC2 만 열어두어서 더 안전하다
AWS 설정
1. EC2 와 RDS 가 같은 리전에 있어야 한다.

( 같은 리전이라고 하면 오른쪽 위에 지역을 말한다.)
2. RDS 에 들어와서 오른쪽 작업 탭 -> EC2 연결 설정에 들어온다

3. 드롭다운을 눌러서 연결 시킬 EC2 를 선택해서 연결 시켜준다.

본격 진행
Jsch 라이러리 의존성 추가
// Jsch - SSH library
implementation ("com.github.mwiede:jsch:0.2.16")
application.properties ( Postgresql 사용 )
# 📦 DB Info
spring.datasource.url=jdbc:postgresql://localhost:[forwardedPort]/[데이터베이스이름]
# 🌐 SSH 터널링 호스트 주소 (예: EC2 퍼블릭 DNS)
ssh.tunnel.host=[ec2주소]
ssh.tunnel.port=22
ssh.tunnel.username=[ec2 user name: 기본 ubuntu]
ssh.tunnel.key=classpath:[.pem 키 경로]
rds.database_endpoint=[rds uri]
rds.database_port=[db port]
# 👤 인증 정보
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=[db user name]
spring.datasource.password=[db user password]
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:[forwardedPort]/[데이터베이스이름]
localhost 는 ec2 -> rds 로 접속하기 때문에 localhost 로 지정해준다.
SSH 로 연결 시켜줄 Config 를 작성 해준다.
@Profile("!test")
@Component
class SshCommandConfig(
@Value("\${ssh.tunnel.host}")
private val sshHost: String,
@Value("\${ssh.tunnel.port}")
private val sshPort: Int,
@Value("\${ssh.tunnel.username}")
private val sshUser: String,
@Value("\${ssh.tunnel.key}")
private val sshKeyPath: String,
@Value("\${rds.database_endpoint}")
private val dbEndpoint: String,
@Value("\${rds.database_port}")
private val dbPort: String,
) {
lateinit var session: Session
@PreDestroy
fun destroy() {
if (session.isConnected) {
session.disconnect()
}
}
@Bean
fun sshSession(): Int {
try{
val classPathResource = ClassPathResource(sshKeyPath)
if (!classPathResource.exists()) {
throw FileNotFoundException("❌ 리소스가 classpath에 존재하지 않음: aws/was_key.pem")
}
val tempKeyFile = File.createTempFile("temp-key", ".pem").apply {
outputStream().use { classPathResource.inputStream.copyTo(it) }
deleteOnExit() // JVM 종료 시 자동 삭제
}
val jsch = JSch()
jsch.addIdentity(tempKeyFile.absolutePath)
val session = jsch.getSession(sshUser, sshHost, sshPort)
val config = Properties()
config["StrictHostKeyChecking"] = "no"
session.setConfig(config)
session.connect()
val port = session.setPortForwardingL(0, dbEndpoint, Integer.parseInt(dbPort))
return port
}catch (ex: Exception){
throw RuntimeException("Failed to create SSH session", ex)
}
}
}
jsch.addIdentity(tempKeyFile.absolutePath)
이 부분에서 keyPath 를 넣어줘야 하는데 키 패스가 안읽혀서 임의의 파일을 생성해주고 주소를 넣는 방식으로 했다.
@Profile("!test")
@Component
class SshDataSourceConfig(
private val initializer: SshCommandConfig
) {
@Bean("dataSource")
@Primary
fun dataSource(properties: DataSourceProperties): DataSource {
val forwardedPort = initializer.sshSession()
val url = properties.url.replace("[forwardedPort]", forwardedPort.toString())
return DataSourceBuilder.create()
.url(url)
.username(properties.username)
.password(properties.password)
.driverClassName(properties.driverClassName)
.build()
}
}
SSH 로 접속이 완료 되었다면,
val forwardedPort = initializer.sshSession()
포워딩 시킨 포트로 db를 접속이 된다.

'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
[Spring] NCP SMS 인증번호 시스템 구현 (1) | 2024.12.03 |
---|---|
[Spring] ServletRequest 캐싱 (ContentCachingRequestWrapper) (0) | 2024.12.02 |
[Spring] 상대방 채팅 읽음 감지 (1) | 2024.11.17 |
[spring] Cache 조회 성능을 최적화 Redis + Kotlin (0) | 2024.11.14 |
[WebSoket] Spring + SocketJs 사용하기 ( 테스트 Html코드 공유 ) (0) | 2024.11.02 |