프로젝트/여행지 오픈 API

ES 서버 Nginx 설정(xpack 보안 설정)

블랑v 2023. 11. 8. 15:12

문제

해킹 당한 이후 ES에 계정과 보안을 강화했다..

 

보안 이슈로 계정을 추가하고, yml에 xpack을 추가한 이후, 스프링부트에서 연동이 되지 않는다.

이는 내 서버가 https가 적용되지 않았기 때문이다. 기존 springboot 연동 urls는 http로 시작했다.

yml 중 일부

Nginx 설치

https://gist.github.com/woorim960/dda0bc85599f61a025bb8ac471dfaf7a

[Nginx를 이용하여 https 적용하는 법

Nginx를 이용하여 https 적용하는 법. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com](https://gist.github.com/woorim960/dda0bc85599f61a025bb8ac471dfaf7a)

어쨌든 잘 인증된 모습. SSAFY 도메인이 걸리긴 하지만..

conf 설정

# Elasticsearch용 HTTPS 서버 블록
server {
    listen 443 ssl;
    server_name es.your_domain.com; # Elasticsearch 도메인으로 변경해야 함

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem; # 실제 인증서 경로로 변경
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem; # 실제 개인 키 경로로 변경

    location / {
        proxy_pass http://localhost:9200; # 실제 Elasticsearch 서버 주소로 변경 가능
        proxy_http_version 1.1;
        proxy_set_header Connection "Keep-Alive";
        proxy_set_header Proxy-Connection "Keep-Alive";
    }
}

# Kibana용 HTTPS 서버 블록
server {
    listen 443 ssl;
    server_name kibana.your_domain.com; # Kibana 도메인으로 변경해야 함

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem; # 실제 인증서 경로로 변경
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem; # 실제 개인 키 경로로 변경

    location / {
        proxy_pass http://localhost:5601; # 실제 Kibana 서버 주소로 변경 가능
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

# HTTP에서 HTTPS로 리디렉션을 위한 서버 블록
server {
    listen 80;
    server_name es.your_domain.com kibana.your_domain.com; # 위에서 사용된 도메인들로 변경

    location / {
        return 301 https://$host$request_uri;
    }
}

이 설정에서 중요한 부분들을 설명하자면:

  • listen 443 ssl은 Nginx가 443 포트에서 SSL/TLS 연결을 수신하도록 설정한다.
  • ssl_certificate와 ssl_certificate_key 지시어는 각각 Let's Encrypt에서 발급받은 인증서와 개인 키 파일의 경로를 지정한다.
  • proxy_pass는 실제 서비스가 실행 중인 호스트와 포트로 요청을 전달한다.
  • server_name은 도메인 이름을 지정하며, 이를 통해 여러 서비스를 구분할 수 있다.

위 설정은 두 서비스가 각기 다른 도메인을 가지고 있다고 가정했다. 만약 같은 도메인에서 다른 경로로 서비스를 구분하려면 location 블록을 조정해야 한다.

이 설정을 적용한 후에는 Nginx 서비스를 재시작해야 한다.

결과적으로 내 경우는 다음과 같이 설정했다.

  GNU nano 4.8                                                               httpsettings.conf                                                               Modified  
# HTTP 트래픽을 HTTPS로 리디렉션
server {
    listen 80;
    server_name k9b205a.p.ssafy.io;

    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS 설정
server {
    listen 443 ssl;
    server_name k9b205a.p.ssafy.io;

    ssl_certificate /etc/letsencrypt/live/k9b205a.p.ssafy.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/k9b205a.p.ssafy.io/privkey.pem;

    # Kibana 리버스 프록시 설정
#    location /kibana {
#        proxy_pass http://localhost:5601;
#        proxy_http_version 1.1;
#        proxy_set_header Upgrade $http_upgrade;
#        proxy_set_header Connection 'upgrade';
#        proxy_set_header Host $host;
#        proxy_cache_bypass $http_upgrade;
#    }

    # Elasticsearch 리버스 프록시 설정
    location / {
        proxy_pass http://localhost:9200;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

 

 

키바나의 경우 아예 다른 도메인으로 할당하고, ES에 443 포트를 통해 씌울 수 있게 하였다.

 

이후 nginx -t를 통해 테스트를 해보자.

도메인 이름이 중복된다는 경고가 있긴 하나, 각각 다른 location 설정으로 인해 문제 없을 것이다.

테스트 이후 nginx를 재시작하였다.

 

 

Springboot 변경 사항

    @Override
    @Bean //bean 등록해줄 것. 해당 설정은 Http일때 사용했음
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(host + ":" + port)
                .usingSsl() //ssl 사용 설정
                .withBasicAuth(username, password)
                .build();

        return RestClients.create(clientConfiguration).rest();
    }

 

사실 기존 config에서 ssl 사용 설정을 추가하고, BasicAuth 계정 정보를 추가했다.

또한 기존 포트는 80이었지만, https 사용으로 인해 443으로 변경하였다.