블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

배포 자동화 시스템을 Packer와 Ansible을 이용해서 만드려고 하나씩 살표보는데, Ansible이 SSH 기반이다.

SSH로 다른 호스트를 접근하려면, 처음에, 해당 호스트의 FingerPrint를 등록할것인지를 물어보는데, 이로 인해서 Ansible 스크립트를 처음 실행할때, 이 물어보는 프롬프트 때문에, 스크립트가 중간에 멈추거나 또는 입력을 받지 못해서 대상 호스트로 접속이 안될 수 있다.


한번 Finger Print를 등록해놓으면, 다음부터는 물어보지 않기 때문에 문제는 없지만, 이를 해결하기 위해서는 처음에도 물어보지 않도록 미리 등록을 해놓아야 한다.


대략 내용을 보니, Finger Print를 등록하는 프롬프트에서 등록을 하게 되면, 해당 호스트는 ~/.ssh/known_hosts 라는 파일에 등록이 된다. 


미리 등록하는 방법은 여러가지 방법이 있는데, 키 체킹등을 패스하는 방법등을 사용하면 보안상 문제가 될 수 있기 때문에 (https://stackoverflow.com/questions/32297456/how-to-ignore-ansible-ssh-authenticity-checking 많은 사람들이 Ansible의 경우 키 체킹을 패스 하는 방법을 쓰는데, MINTM Attack 에 취약하고, 이렇게 보안 취약점이 생기는 만큼 ) , 단순하게 "되는 방법보다", "보안적으로 문제가 없는" 방법을 찾아봐야 겠다.


-- 1/13일 추가


known_host에 호스트명을 추가하면 되는데, 방법은


ssh-keyscan -t rsa host명 >> ~/.ssh/known_host


또는 여러 호스트를 한꺼번에 입력하고자 할때는


ssh-keyscan -t rsa -f host명들 이들어있는 파일명 >> ~/.ssh/known_host


구글 클라우드 서버의 HTTP 포트를 SSH 로 터널링해서 로컬에서 접속하기


조대협 (http://bcho.tistory.com)


구글 클라우드 VM에 서버를 설치한 후 웹을 접근하고자 할때, 설치한 애플리케이션이 ACL (접근 제어) 처리가 안되어 있는 애플리케이션이 있을 수 있다. 특히 관리자 콘솔 같은 경우에 이런 경우가 많은데, 아파치 에어플로우 역시도 설치 후에 웹 서버를 띄우면 포트가 모두 퍼블릭으로 오픈되기 때문에 관리자만 액세스가 가능하도록 ACL 처리를 할 필요가 있다.


이를 위한 방법으로는 몇가지가 있는데


  1. 방화벽으로 특정 포트만 허용 하는 방법
  2. 앞에 nginx나 apache를 넣어서 HTTP BASIC AUTH등 인증 방식을 추가하는 방법
  3. Google Cloud Identity Aware Proxy를 이용하여, 구글 클라우드 계정 사용자에게 접근 권한을 부여 하는 방법
  4. 해당 HTTP 포트를 SSH로 터널링 하는 방법

1번 방법은 IP 가 바뀌면 접근 제어 하기가 번거로우니 패스, 2번은 웹서버 깔아야 하니 패스, 3번은 제일 좋은 방법인데, 로드밸런서등 구체적인 설정을 해야 해서 패스. 그래서 오늘은 가장 간단한 4번 방법을 설명한다.

4번 방법은 로컬에서 localhost:2222를 접속하면 구글 클라우드 상의 인스턴스:8080 으로 포워딩을 해준다. 이때 프로토콜을 SSH를 통해서 터널링이 된다.

매우 간단하게 할 수 있는데, 로컬에 gcloud SDK가 깔려 있을때

gcloud compute ssh {인스턴스명} --project {내프로젝트ID} --zone {인스턴스가 있는 존 이름} --ssh-flag="-L" --ssh-flag="{랩탑에서 접속할 포트번호}:localhost:{인스턴스의 포트 번호}"

로 기입해주면 된다.

예를 들어 terrycho-ml 프로젝트의 us-central1-f 존에 있는 hello-airflow 인스턴스의 8080 포트를 로컬에서  localhost:2222로 접근하도록 포워딩 설정을 할 경우 다음과 같이 하면 된다.


gcloud compute ssh hello-airflow --project terrycho-ml --zone us-central1-f --ssh-flag="-L" --ssh-flag="2222:localhost:8080"

구글 클라우드 VM으로 SSH  접속하기


조대협 (http://bcho.tistory.com)


클라우드에서 VM을 생성하면, 이 VM에 접속하기 위해서 리눅스 VM의 경우 일반적으로 SSH 연결을 사용한다.

구글 클라우드에서 SSH를 이용하여 VM에 접속하는 방법을 알아본다.


1. SSH 키페어 생성

ssh-keygen 명령어를 이용하여 다음과 같이 RSA 키페어를 생성한다.

%ssh-keygen -t rsa -C "구글계정명"



2. 키페어가 생성이 되었으면 *.pub으로 끝나는 이름의 퍼블릭키의 내용(텍스트)를 복사한후, 콘솔창에서 "Compute Engine > Metadata > SSH Keys"  부분에 복사한 텍스트를 붙여 넣어서 키를 등록한다.




3. 키 등록이 끝났으면, 이 키를 이용하여 SSH로 접속한다.

% ssh -i [Private 키 파일] 계정@호스트명



Fabric을 이용한 간단한 Tomcat deploy

프로그래밍/Python | 2013.01.29 18:46 | Posted by 조대협

Tomcat war deploy시, 가장 이상적인 방법은 

tomcat stop > copy war > start 순서이다.

아래는 간단하게 Python 기반의 Fabric을 이용하여, EC2상에서 pem (SSH)를 이용하여, Host들에 deploy하는 과정을 정의함


#fabfile.py

from fabric.api import run,env,execute,task

from fabric.operations import local,put


def tomcat_cluster():

        env.user ='root'

        env.hosts=['host1.server.com','host2.server.com'] # list of server setting

        env.key_filename='~/pem/pemfile.pem' # pem file


def hostname():

        run('uname -a')


def start():

        run('/etc/init.d/tomcat6 start')  # tomcat instance stop


def stop():

        run('/etc/init.d/tomcat6 stop') # tomcat instance stop


def copy():

        put('./dummy.war','/root/war') # file copy


def deploy(): 

        execute(stop)

        execute(copy)

        execute(start)

해당 파일을 fabfile.py에 저장후에

%fab tomcat_cluster deploy

해주면 아래와 같은 순서로 수행됨

host1.stop()

host1.copy()

host1.start()

host2.stop()

host2.copy()

host2.start()


기타 참고할만한 명령어
- sudo
- get : 파일 copy 해옴 
- local : local machine에서 명령어 수행
- with cd('{dir}') : 특정 디렉토리를 베이스로 명령어등을 수행할때 사용


※ 참고 : 외부에서 Host 명을 dynamic하게 받는 방법

--------------------------------

외부에서 host list 받는 방법

def deploy(lookup_param):

    # This is the magic you don't get with @hosts or @roles.

    # Even lazy-loading roles require you to declare available roles

    # beforehand. Here, the sky is the limit.

    host_list = external_datastore.query(lookup_param)

    # Put this dynamically generated host list together with the work to be

    # done.

    execute(do_work, hosts=host_list)

    

실행할때는

$ fab deploy:app


------ 또는 -----------

# Marked as a publicly visible task, but otherwise unchanged: still just

# "do the work, let somebody else worry about what hosts to run on".

@task

def do_work():

    run("something interesting on a host")


@task

def set_hosts(lookup_param):

    # Update env.hosts instead of calling execute()

    env.hosts = external_datastore.query(lookup_param)

    

$ fab set_hosts:app do_work

One benefit of this approach over the previous one is that you can replace do_work with any other “workhorse” task:


$ fab set_hosts:db snapshot

$ fab set_hosts:cassandra,cluster2 repair_ring

$ fab set_hosts:redis,environ=prod status