Http -> Https

sein lee·2024년 6월 26일
0

project

목록 보기
3/3
post-thumbnail
post-custom-banner

프로젝트 철수하는 주에 갑자기 고객사에서 인터페이스 테스트가 안된다는 연락을 받았다..

이유는.. 기존에 api 는 http 호출이었는데
갑자기 https 호출을 한다는것 ..!

Https는 데이터 전송에 암호화가 걸리는 것이기 때문에 생각보다 고려해야할 게 너무 많아서 오래 걸렸다..

간단하게 작업을 나열하자면

  1. SSL/TLS 인증서 발급 및 설정
    서버에 인증서 받기 -> 이부분은 고객사와 서버관리팀에 요청해서 발급받고 설정할 수 있었다.
  2. 그 외 설정
    • 포트 변경
      기존에 9100포트를 사용하였지만 보안 포트인 443 포트로 변경
    • kubenetes ingress
      도메인 설정
      서비스 연결
      SSL/TLS 설정 등
    • 인터페이스 설정
      SSL/TLS 설정
      port, ip 변경
      소스 수정 등

1. SSL/TLS 인증서

(.key 파일 없고 .pem 파일만 있을 때)
A. .key파일 생성

openssl rsa -in key.pem -out cert.key

B. 도메인에 대하여 인증서 등록

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./tls/project-https-secret/tls.key -out ./tls/project-https-secret/tls.crt -subj 도메인명

C. k8s 에서 인증서를 사용할 수 있도록 생성

kubectl -n project명 create secret tls twinreader-https --key ./tls/project-https-secret/tls.key --cert ./tls/project-https-secret/tls.crt

D. nginx.yaml 에서 사용할 https port 선언(예시) 및 재기동

spec:
  type: NodePort
  externalIPs:
    - IP입력
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 80
    - name: https
      port: 443
      protocol: TCP
      targetPort: 443

E. ingress.yaml 설정
가지고 있는 ingress 폴더에 하위에 생성한 secret 선언

2. 그 외 설정

A. 인터페이스 SSL/TLS 설정
Keystore.p12생성
tls 디렉토리 접근 후

openssl pkcs12 -export -in /home/agilesoda/install/config/nginx/tls/twinreader-https-secret/tls.crt -inkey /home/agilesoda/install/config/nginx/tls/twinreader-https-secret/tls.key -out keystore.p12 -name tomcat

생성된 keystore.p12를 인터페이스에 적용
<application.properties>

server.ssl.key-store=/keystore.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=패스워드

그리고 나는 도커로 말아서 올릴거니까
Dockerfile 에

ADD /install/keystore.p12 keystore.p12

이거 추가

그리고그리고 Kubernetes 클러스터에 배포하기 위한 deployment.yaml 수정

ports:
  - name: https
    protocol: TCP
    #appProtocol: https
    port: 443
    targetPort: 9000
  - name: http
    protocol: TCP
    port: 9100
    targetPort: 9100

B. 개발 소스 수정
org.apache.coyote.http11.Http11NioProtocol"을 사용하여 HTTP/1.1 NIO 프로토콜을 지정하고 커넥터가 사용하는 포트를 9100 으로 설정..

@Configuration
  public class TomcatConfig {
    
    @Bean
    public ServletWebServerFactory servletContainer() {
      TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
      tomcat.addAdditionalTomcatConnectors(createStandardConnector());
      return tomcat;
    }
    
    private Connector createStandardConnector() {
      Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
      connector.setPort(9100);
      return connector;
    }
  }

C. Ingress 설정
클러스터 외부에서 내부 서비스로 HTTP 및 HTTPS 경로를 라우팅하는 규칙을 설정
<project-pension-ingress.yaml>

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: project
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/secure-backends: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    #nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET,POST"
spec:
  tls:
  - hosts:
    - "도메인명"
    secretName: twinreader-https
  rules:
  - host: "도메인명"
    http:
      paths:
      - path: /api/v1/aiocrSyncLoad(/|$)(.*)
        backend:
          serviceName: project
          servicePort: 443

yaml 파일 수정후 반영(kubectl delete, apply..)

이슈요약..

처음엔 인증서만 받아서 보안포트 사용하면 되는거겟지~ 했는데
우선 인증서 발급과 반영에 대해 무지해서 도움을 많이 받았다.

인증서 적용 후 내 인터페이스의 POST 방식의 호출만 호출이 안되어서 그부분도 확인해보니 redirect 가 이상한 곳으로 가길래 ingress.yaml 의 rewrite 부분을 그냥 주석 해버렸더니 해결 되었었다.
해당 에러는

Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]

이렇게 생겼었고

#logging.level.org.springframework=debug
#logging.level.org.springframework.web=debug
#logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG

해당 설정값을 추가해 자세히 로그를 보니 알 수 있었다.

다음으론 인터페이스 내부였다..
인터페이스 내부에는 회사 제품을 호출하고 결과를 받아서 그결과를 보정한 후 전달하게 되는데
https로 들어와서 제품 호출하고 제품에서 http 로 다시 인터페이스를 콜백하는데 그 통신이 안되는것이었다..
그래서 인터페이스 deployment.yaml 을 보면 https 와 http 포트를 구분지어서 통신에따라 다르게 들어오게 처리 해줬다!

이런식으로 port 가 두개!

느낀점

그.. k8s 버전도 중요.. 꼭 버전에 맞는걸로 테스트 해보시길.. 버전마다 안되는 설정값이 있어서 이것도 애먹었다...

이제 앞으로는 처음 개발 시에 통신에 대해 정하고 시작하기로 다짐했다.
물론 당연히 데이터가 주고받는일에 단순히 내부통신이라고 보안을 생각못한 내잘 못도 있지만..
같이 테스트 하고 컨펌해줬으면서 갑자기 바꾸는 갈대 같은 고객사는... 어쩔 수 없지 뭐....

아직도 서버는 잘 모르겠지만...이렇게 틈틈이 접하다보면 괜찮아지겟지?

profile
개발감자
post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 9월 8일

답글 달기