Redis 500 No route to host 에러 - 1편

2025. 7. 20. 21:52·Cloud/AWS

최근 스노로즈 서버의 프리 티어가 만료되어 새로운 AWS 계정으로 이전하는 작업을 진행했다.

그런데 그 뒤로 자꾸 로그인 시 500 에러가 발생했다.

ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis] with root cause

java.net.NoRouteToHostException: No route to host

        at java.base/sun.nio.ch.Net.pollConnect(Native Method)

        at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)

        at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)

        at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:337)

        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:335)

        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:776)

        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)

        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)

        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)

        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)

        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)

        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

        at java.base/java.lang.Thread.run(Thread.java:840

 

내부 로그를 확인해보면 No Route to host 에러가 발생하는 것을 확인할 수 있었다.

이 에러는 왜 발생하는 것일까? 지금까지의 해결 방법을 정리해 보았다.

 

1. 네트워크 확인

No route to host 에러는 EC2 인스턴스에서 ElastiCache(Redis) 서버의 IP 주소로 가는 경로 자체를 찾지 못하는 상태이다.

따라서 EC2와 ElastiCache 서브넷 간의 라우팅 테이블과 NACL을 확인해 보았다.

 

 

public routing table과 private routing table 둘 다 local 타겟으로 VPC의 전체 IP 대역(10.0.0.0/16)이 설정되어 있는 것을 확인할 수 있었다.

 

 

NACL의 경우에는 모든 트래픽을 허용해둔 상태였다.

따라서 EC2 인스턴스가 ElastiCache 서버에 도달하는 과정에서는 문제가 없는 것으로 판단했다.

 

2. 보안 그룹 확인

혹시 ElastiCache 보안 그룹의 인바운드 규칙에 6379 포트 트래픽이 허용되어 있지 않기 때문에 문제가 발생하는 것은 아닐지 의심이 들어 보안 그룹도 확인해 보았다.

 

 

인바운드 규칙은 모든 IP(0.0.0.0/0)에서 Redis 포트(6379)로 접속하는 것을 허용하는 상태였다.

해당 방식은 공격에는 취약할 수 있지만 No route to host 문제에 영향을 미치는 요소는 아니다.

문제가 해결된다면 IP 대역을 EC2의 보안 그룹 ID로 바꾸면 될 것 같다.

 

3. 전송 중 암호화 확인

현재 Redis에는 전송 중 암호화가 활성화되어 있다.

하지만 JAVA 애플리케이션의 RedisConfig.java에서는 SSL을 사용하지 않도록 작성되어 있다.

// RedisConfig.java

@Bean
public LettuceConnectionFactory redisConnectionFactory(ClientResources clientResources) {
    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
    LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
        //.useSsl()
        //.and()
        .clientResources(clientResources)
        .commandTimeout(Duration.ofSeconds(10))
        .shutdownTimeout(Duration.ZERO)
        .build();

    return new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
}

 

따라서 .useSsl() 부분의 주석을 해제하여 ssl 암호화를 활성화하거나, Redis에서 전송 중 암호화를 비활성화하여 설정을 맞춰주면 된다.

 

해당 설정을 변경한 이후 telnet 연결을 진행하면 EC2와 Redis가 연결되는 것을 확인할 수 있었다.

root@ip-10-0-13-22:~# telnet master.for-redis-use.ltj62h.apn2.cache.amazonaws.com 6379
Trying 10.0.158.215...
Connected to for-redis-use-001.for-redis-use.ltj62h.apn2.cache.amazonaws.com.
Escape character is '^]'.

 

4. Java의 DNS 캐시 확인

Java는 자체적으로 DNS 캐시를 관리한다.

이전에 잘못된 IP로 접속을 시도했던 기록이 JVM 내부에 남아있어, OS와는 다른 정보로 접속을 시도하고 있을 수 있다.

 

EC2 인스턴스 재부팅으로 OS와 JVM의 네트워크 관련 상태와 캐시를 초기화해도 여전히 접속 부분에서 문제가 발생했다.

따라서 애플리케이션의 시작 스크립트인 start.sh에서 Java DNS 캐시를 비활성화했다.

nohup java \
    -Dnetworkaddress.cache.ttl=0 \
    -Dnetworkaddress.cache.negative.ttl=0 \
    -jar \
    -Dspring.datasource.url=...

 

해당 코드를 통해 JVM이 DNS 조회 결과를 캐싱하지 않도록 하여, telnet과 동일하게 매번 OS의 네트워크 설정을 통해 경로를 찾도록 설정했다.

 

5. DNS 대신 IP 주소

telnet으로는 접속이 가능한데 Java에서만 접속이 안 되고 있다.

따라서 이제는 Redis의 DNS 이름을 해석하는 과정에서 문제가 발생한다고 생각하게 되었다.

이전에 telnet으로 접속했을 때 Redis의 IP 주소가 출력되었다.

Redis는 꺼지지 않기 때문에 IP 주소가 바뀌지 않는다고 판단하고, Parameter Store에 REDIS_HOST 파라미터에 IP 주소를 입력하여 연결을 시도했다.

 

의외로 이 방법을 통해 문제가 해결됐다.

'Cloud/AWS' 카테고리의 다른 글
  • Redis 500 No route to host 에러 - 2편
  • AWS ELB 및 ASG 정리
  • 백엔드 코드는 어떻게 S3에 접근할 수 있을까?
  • AWS EC2 정리
단축키실행해보세요
단축키실행해보세요
공대생
  • 단축키실행해보세요
    Ctrl + Shift + ESC
    단축키실행해보세요
  • 전체
    오늘
    어제
    • 분류 전체보기 (171)
      • 외부 활동 (4)
      • BOJ (36)
        • Python (24)
        • C++ (12)
        • Java (0)
      • Hacking (91)
        • Crypto (4)
        • Forensics (2)
        • Mobile Hacking (5)
        • Reversing (21)
        • System (21)
        • Web Hacking (38)
      • Cloud (14)
        • Serverless (1)
        • AWS (8)
      • ML (5)
      • Data Structure (16)
      • Git (0)
      • DevOps (0)
        • Terraform (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    System
    python
    ML
    cloud
    백준
    S3
    backjoon
    EC2
    Systemhacking
    pwnable
    SAA
    CodeEngn
    basicrce3
    bWAPP
    htmlinjection
    자료구조
    Dreamhack
    유석종교수님
    부하테스트
    c
    beebox
    AWS
    Reflected
    AI
    XPath
    Redis
    SISS
    datastructure
    Reversing
    acc
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
단축키실행해보세요
Redis 500 No route to host 에러 - 1편
상단으로

티스토리툴바