Docker의 SSH 터널

4668 단어
Docker 이미지로 마무리할 크롤러를 만들고 있습니다. 크롤러는 원격 MySQL 데이터베이스에 데이터를 기록합니다. 그러나 문제가 있습니다. 데이터베이스 연결은 SSH 터널을 통해 이루어집니다. 또 다른 문제는 크롤러가 ECS에서 실행될 예정이므로 모든 것(SSH 터널 설정 포함)을 Docker 이미지에 구워야 한다는 것입니다.



이 게시물은 Docker에서 SSH 터널을 통해 원격 MySQL 데이터에 연결하는 과정을 보여줍니다. 이것이 얼마나 안전한지 잘 모르겠습니다. 그리고 아마도 더 나은 방법이 있을 것입니다. 그러나 그것은 시작이고 작동합니다!

SSH 키 쌍



먼저 새 SSH 키 쌍을 생성해야 합니다.

ssh-keygen -N "" -t rsa -f id_rsa


이렇게 하면 암호를 묻는 메시지가 표시되지 않으며 두 개의 파일이 생성됩니다.
  • id_rsa (비공개 키) 및
  • id_rsa.pub (공개 키).

  • 공개 키id_rsa.pub의 내용을 원격 호스트의 ~/.ssh/authorized_keys에 복사합니다. 🚨 전체 공개 키가 한 줄에 있는지 확인하십시오.

    도커파일



    다음으로 Dockerfile 를 설정합니다.

    FROM ubuntu:20.04
    
    RUN apt-get update -qq && \
        apt-get install -y -qq openssh-client mysql-client && \
        rm -rf /var/lib/apt/lists/*
    
    ARG PRIVATE_KEY
    
    RUN mkdir /root/.ssh
    
    COPY $PRIVATE_KEY /root/.ssh/id_rsa
    
    RUN echo "Host *" > ~/.ssh/config && \
      echo " StrictHostKeyChecking accept-new" >> ~/.ssh/config && \
      echo " ControlMaster auto" >> ~/.ssh/config && \
      echo " ControlPath ~/.ssh/%r@%h:%p" >> ~/.ssh/config
    
    COPY tunnel-mysql.sh .
    
    CMD ./tunnel-mysql.sh
    


    이는 다음을 수행합니다.
  • SSH 개인 키를 이미지에 복사합니다.
  • 새 호스트에 연결할 때 확인 메시지를 표시하지 않도록 SSH를 구성합니다. 및
  • BASH 스크립트를 이미지에 복사합니다.

  • 스크립트



    이제 BASH 스크립트입니다.

    #!/bin/bash
    
    echo -n "Creating SSH tunnel to $HOST... "
    ssh -4 -q -N -f -T -M -L 3306:127.0.0.1:3306 $HOST
    echo "Done!"
    
    export MYSQL_PWD=$PASSWORD
    mysql -e 'SHOW DATABASES;' --user $USERNAME -h 127.0.0.1
    
    echo -n "Closing SSH tunnel... "
    ssh -q -T -O "exit" $HOST
    echo "Done!"
    


    이것은 원격 호스트에 대한 SSH 터널을 설정하고 원격 호스트의 MySQL 데이터베이스에 연결하고 간단한 SQL 쿼리를 실행한 다음 SSH 터널을 닫습니다.

    SQL 쿼리는 자리 표시자일 뿐입니다. 수행해야 하는 데이터베이스 상호 작용이 무엇이든 여기로 이동합니다. 제 경우에는 크롤러가 시작되는 곳입니다.

    구축 및 실행


    id_rsa에 지정된 PRIVATE_KEY의 값으로 Dockerfile를 전달하여 이미지를 빌드해 보겠습니다. 이 개인 키는 이미지에 구워질 것입니다. 💡 런타임에 개인 키를 제공하는 것도 똑같이 가능하지만 결국 빌드 시간에 제공하기로 결정했습니다.

    docker build --build-arg PRIVATE_KEY=id_rsa -t docker-ssh-tunnel .
    


    빌드되면 실행하십시오.

    docker run --rm -t --env-file .env docker-ssh-tunnel
    


    다음과 같은 .env 파일의 일부 환경 변수를 통과하고 있습니다(모든 값은 가상입니다!).

    [email protected]
    USERNAME=wookie
    PASSWORD=04cmRXCPJ111coQpuqmHH6Uc
    


    그리고 우리 노동의 열매:

    Creating SSH tunnel to [email protected]... Done!
    +---------------------+
    | Database |
    +---------------------+
    | information_schema |
    | mysql |
    | performance_schema |
    | sys |
    +---------------------+
    Closing SSH tunnel... Done!
    


    멋진!

    오토메이션



    마지막 구성 요소는 이것을 래핑하여 GitLab CI를 사용하여 빌드하도록 합니다. 다음은 .gitlab-ci.yml의 내용입니다.

    stages:
      - build
    
    variables:
      IMAGE_NAME: docker-ssh-tunnel
      TAG_LATEST: $CI_REGISTRY_IMAGE/$IMAGE_NAME:latest
      DOCKER_TLS_CERTDIR: ""
    
    build:
      image: docker:stable
      stage: build
      only:
        - master
      services:
        - docker:dind
      script:
      - cp $PRIVATE_KEY id_rsa
      - docker build --build-arg PRIVATE_KEY=id_rsa -t $TAG_LATEST .
      - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
      - docker push $TAG_LATEST
    

    id_rsa의 내용은 PRIVATE_KEY라는 CI/CD 파일 변수에 저장됩니다. 이 파일은 이미지가 빌드되기 전에 Docker 빌드 컨텍스트로 복사됩니다.



    이제 이미지는 ECS에서 액세스할 수 있는 레지스트리에 저장됩니다. HOST , USERNAMEPASSWORD 값을 보유하도록 ECS 작업에 환경 변수를 설정할 수 있습니다.

    🚨 이 접근 방식에 대한 한 가지 중요한 주의 사항은 Docker 이미지에 액세스할 수 있는 사람은 누구나 SSH 개인 키에도 액세스할 수 있다는 것입니다. (i) 이미지가 안전한 개인 레지스트리에 저장되도록 하고 (ii) 중요한 데이터베이스 자격 증명을 사용하여 위험을 완화할 수 있습니다.

    좋은 웹페이지 즐겨찾기