• HAproxy(High Availability proxy)는 고가용성 프록시를 의미 → HAProxy는 소프트웨어 기반 L7 스위치
  • HAproxy는 C 언어로 작성
  • 무료 오픈소스 프로그램
  • HAproxy는 TCP/HTTP 로드 밸런서로 프록시 솔루션에 사용
  • HAproxy의 일반적인 용도는 웹서버, DB 서버 등 부하를 분산시키는 용도로 많이 사용
  • HAProxy는 기존의 하드웨어 스위치를 대체하는 소프트웨어 로드 밸런서 → 네트워크 스위치에서 제공하는 L4, L7 기능 및 로드 밸런서 기능을 제공
  • 설치가 쉽고 빠르기에 서비스 이중화(HA- High Availability)를 구성하는데 주로 사용

1. HAproxy 로드밸런서 테스트 준비사항 → VM 환경에서 진행

  • HAproxy를 설치할 VM 1대, 웹서버 VM 2대, 테스트 서버 1대
    1. HAproxy 서버 → 192.168.100.101, centos7, hostname : haproxy, 60000 → 80포트로 proxy
    2. 첫번째 web 서버 → 192.168.100.201, centos7, hostname: web1
    3. 두번째 web 서버 → 192.168.100.202, centos7, hostname: web2
    4. 테스트 서버 → 192.168.100.10, centos7, hostname: test

2. HAproxy.conf 옵션

  • haproxy.cfg 의 옵션은 (https://cbonte.github.io/haproxy-dconv/) 에서 자세하게 확인 가능
  • 기본적인 옵션만 아래 설명 → 여러 섹션으로 나누어져 있으며 섹션 하단에 파라미터를 추가하는 방식으로 구성

2.1. global 구간

  • -daemon
    • 백그라운드에서 HAproxy 서비스 실행
    • 데몬형식 fork 하면서 실행 하는 파라미터
    • 만약 daemon을 추가 하지 않을 경우 포그라운드에서 실행 → 실행할 때 &를 추가하여 명시적으로 백그라운드에서 실행되게 해야함
  • -maxconn
    • 최대 연결 수를 지정
    • (ulimit -n) 을 통해 해당 서버의 기본 프로세스가 오픈 할 수 있는 갯수 만큼 지정 가능

2.2. defaults 구간

  • -mode (http,tcp,health)
    • tcp→ 해당 포트에 대한 어플리케이션 프록시
    • http→ http 인스턴스에서 작동
    • health→ 단순한 health check 모드
  • -timeout connect
    • 전체 외부 클라이언트에서 실제 real 서버 까지의 time out 설정
  • -timeout client
    • 외부 클라이언트에서 vip(virtual IP)까지의 timeout 설정
  • -timeout server
    • vip(virtual IP) 서버에서 실제 real 서버 까지의 timeout 설정

2.3. frontend 구간

  • -bind
    • bind 는 apache 의 binding 설정과 비슷 하며, 해당 서버로 listening 되는 아이피와 포트를 지정
  • -default_backend
    • frontend 에서 받은 정보를 backend server로 보낼 이름을 지정
    • servers 라는 backend 설정된 아이피로 포워딩

2.4. backend servers 구간 → server <name> <address>[:[port]][param*]

  • 위 형태로 명시된 아이피와 포트로 데이터를 전송

2.5. listen 구간

  • frontend + backend 한번에 설정 가능한 섹션


3. HAproxy balance 옵션

  • backend 에서 사용 할 balancing 알고리즘을 설정 가능

3.1. roundrobin

  • 순서대로 데이터를 전송

3.2. static-rr

  • 서버에 weight 가중치를 부여해, 부여된 가중치에 따라 데이터 전송

3.3. balance_url_param

  • HTTP GET 요청에 대해서 특정 패턴이 있는지 여부 조사후 조건에 맞는 서버로 트래픽 전송
  • 조건이 없는 경우 roundrobin 으로 트래픽 전송

3.4. balance hdr

  • HTTP Header 에서 hdr(name) 으로 지정된 조건이 있는 경우에 대해서만 트래픽 전송
  • 조건이 없는경우 roundrobin 으로 트래픽 전송


4. HAproxy 패키지 설치

4.1. 첫번째 방법. yum으로 haproxy 패키지 설치

  • HAproxy는 버전에 따라 설정이 약간씩 다르기에 필요한 버전을 수동으로 다운받는게 좋음
    $ yum -y install haproxy

4.2. 두번째 방법. HAproxy 패키지 수동으로 설치 → HAproxy 2.3.9 버전 설치

  • 아래 명령어를 입력하여 haproxy 2.3.9 버전 설치 파일을 다운로드

    $ cd /usr/local/lib
    
    # haproxy 2.3.9 버전 파일 설치
    $ curl -O http://www.haproxy.org/download/2.3/src/haproxy-2.3.9.tar.gz
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 2860k  100 2860k    0     0   564k      0  0:00:05  0:00:05 --:--:--  672k
    
    # 다운받은 haproxy 2.3.9 버전 설치 파일 확인
    $ ls /usr/local/lib
    haproxy-2.3.9.tar.gz
  • 설치파일을 압축해제
    $ tar zxf haproxy-2.3.9.tar.gz
    $ ls -al /usr/local/lib
    total 2868
    drwxr-xr-x.  3 root root      55 Aug  1 13:09 .
    drwxr-xr-x. 12 root root     131 Apr 30  2020 ..
    drwxrwxr-x  11 root root    4096 Mar 30 16:38 haproxy-2.3.9
    -rw-r--r--   1 root root 2928660 Aug  1 13:08 haproxy-2.3.9.tar.gz
  • HAproxy를 설치하기 전에 의존성 패키지를 설치
    $ yum install gcc openssl openssl-devel pcre-static pcre-devel systemd-devel -y
  • HAproxy 2.3.9 설치 옵션을 설정
    1. TARGET=linux-glibc → HAProxy 2.0 부터는 "linux2628" 대신에 "linux-glibc" 로 "TARGET"이 변경
    2. USE_OPENSSL=1 → SSL 인증서를 활성화 하기 위해서 USE_OPENSSL를 활성화
    3. USE_PCRE=1 → 펄(PERL) 호환 정규 표현식을 사용하기 위해 활성화
    4. USE_ZLIB=1 → http 압축을 이용하기 위해 활성화
    5. USE_SYSTEMD=1 → systemd 를 통해서 서비스를 컨트롤 하기 위해서 USE_SYSTEMD도 활성화
      $ cd /usr/local/lib/haproxy-2.3.9
      $ make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1
       CC      src/ev_poll.o
       CC      src/ev_epoll.o
       CC      src/ssl_sample.o
       CC      src/ssl_sock.o
      [...생략]
  • HAproxy를 설치
    $ make install
    ‘haproxy’ -> ‘/usr/local/sbin/haproxy’
    ‘doc/haproxy.1’ -> ‘/usr/local/share/man/man1/haproxy.1’
    install: creating directory ‘/usr/local/doc’
    install: creating directory ‘/usr/local/doc/haproxy’
    ‘doc/configuration.txt’ -> ‘/usr/local/doc/haproxy/configuration.txt’
    ‘doc/management.txt’ -> ‘/usr/local/doc/haproxy/management.txt’
    ‘doc/seamless_reload.txt’ -> ‘/usr/local/doc/haproxy/seamless_reload.txt’
    ‘doc/architecture.txt’ -> ‘/usr/local/doc/haproxy/architecture.txt’
    ‘doc/peers-v2.0.txt’ -> ‘/usr/local/doc/haproxy/peers-v2.0.txt’
    ‘doc/regression-testing.txt’ -> ‘/usr/local/doc/haproxy/regression-testing.txt’
    ‘doc/cookie-options.txt’ -> ‘/usr/local/doc/haproxy/cookie-options.txt’
    ‘doc/lua.txt’ -> ‘/usr/local/doc/haproxy/lua.txt’
    ‘doc/WURFL-device-detection.txt’ -> ‘/usr/local/doc/haproxy/WURFL-device-detection.txt’
    ‘doc/proxy-protocol.txt’ -> ‘/usr/local/doc/haproxy/proxy-protocol.txt’
    ‘doc/linux-syn-cookies.txt’ -> ‘/usr/local/doc/haproxy/linux-syn-cookies.txt’
    ‘doc/SOCKS4.protocol.txt’ -> ‘/usr/local/doc/haproxy/SOCKS4.protocol.txt’
    ‘doc/network-namespaces.txt’ -> ‘/usr/local/doc/haproxy/network-namespaces.txt’
    ‘doc/DeviceAtlas-device-detection.txt’ -> ‘/usr/local/doc/haproxy/DeviceAtlas-device-detection.txt’
    ‘doc/51Degrees-device-detection.txt’ -> ‘/usr/local/doc/haproxy/51Degrees-device-detection.txt’
    ‘doc/netscaler-client-ip-insertion-protocol.txt’ -> ‘/usr/local/doc/haproxy/netscaler-client-ip-insertion-protocol.txt’
    ‘doc/peers.txt’ -> ‘/usr/local/doc/haproxy/peers.txt’
    ‘doc/close-options.txt’ -> ‘/usr/local/doc/haproxy/close-options.txt’
    ‘doc/SPOE.txt’ -> ‘/usr/local/doc/haproxy/SPOE.txt’
    ‘doc/intro.txt’ -> ‘/usr/local/doc/haproxy/intro.txt’
  • 설치된 HAproxy 버전을 확인 → HAproxy 2.3.9로 잘 설치된 것을 확인
    $ /usr/local/sbin/haproxy -v
    HA-Proxy version 2.3.9-53945bf 2021/03/30 - https://haproxy.org/
    Status: stable branch - will stop receiving fixes around Q1 2022.
    Known bugs: http://www.haproxy.org/bugs/bugs-2.3.9.html
    Running on: Linux 3.10.0-1160.36.2.el7.x86_64 #1 SMP Wed Jul 21 11:57:15 UTC 2021 x86_64
  • HAProxy 서비스 예제 파일을 다운로드
    $ curl "http://git.haproxy.org/?p=haproxy-2.3.git;a=blob_plain;f=contrib/systemd/haproxy.service.in" -o /etc/systemd/system/haproxy.service
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                   Dload  Upload   Total   Spent    Left  Speed
    100  1405    0  1405    0     0    550      0 --:--:--  0:00:02 --:--:--   550
  • HAproxy 서비스 예제 파일 수정

    1. $CONFIG 값 설정 → /etc/haproxy/haproxy.cfg

    2. $EXTRAOPTS 값 설정 → /run/haproxy-master.sock

    3. $PIDFILE 값 설정 → /run/haproxy.pid

      $ vi /etc/systemd/system/haproxy.service
      [Unit]
      Description=HAProxy Load Balancer
      After=network-online.target
      Wants=network-online.target
      
      [Service]
      EnvironmentFile=-/etc/default/haproxy
      EnvironmentFile=-/etc/sysconfig/haproxy
      Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock"
      
      # 수정 전 내용 아래
      ExecStartPre=@SBINDIR@/haproxy -f $CONFIG -c -q $EXTRAOPTS
      ExecStart=@SBINDIR@/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS
      ExecReload=@SBINDIR@/haproxy -Ws -f $CONFIG -c -q $EXTRAOPTS
      
      # 수정 후 내용 아래
      ExecStartPre=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q -S /run/haproxy-master.sock
      ExecStart=/usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock
      ExecReload=/usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -c -q -S /run/haproxy-master.sock
      
      ExecReload=/bin/kill -USR2 $MAINPID
      KillMode=mixed
      Restart=always
      SuccessExitStatus=143
      Type=notify
      
      # The following lines leverage SystemD's sandboxing options to provide
      # defense in depth protection at the expense of restricting some flexibility
      # in your setup (e.g. placement of your configuration files) or possibly
      # reduced performance. See systemd.service(5) and systemd.exec(5) for further
      # information.
      
      # NoNewPrivileges=true
      # ProtectHome=true
      # If you want to use 'ProtectSystem=strict' you should whitelist the PIDFILE,
      # any state files and any other files written using 'ReadWritePaths' or
      # 'RuntimeDirectory'.
      # ProtectSystem=true
      # ProtectKernelTunables=true
      # ProtectKernelModules=true
      # ProtectControlGroups=true
      # If your SystemD version supports them, you can add: @reboot, @swap, @sync
      # SystemCallFilter=~@cpu-emulation @keyring @module @obsolete @raw-io
      
      [Install]
      WantedBy=multi-user.target
  • HAproxy가 사용할 디렉토리를 생성
    $ mkdir -p /etc/haproxy
    $ mkdir -p /var/log/haproxy
    $ mkdir -p /var/lib/haproxy
    $ mkdir -p /etc/haproxy/certs
    $ mkdir -p /etc/haproxy/errors/


5. haproxy.conf 파일 생성 또는 수정

5.1. haproxy.conf 파일에 들어가는 내용 옵션 확인

$ vi /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2         # syslog. UDP 514번 포트 Open 필요

    chroot      /var/lib/haproxy         # 모든 동작은 /var/lib/haproxy에서 수행, 보안 상승
    pidfile     /var/run/haproxy.pid     # 실행 pid명
    maxconn     4000                     # 프로세스 당 최대 연결 수치
    user        haproxy                  # haproxy 서비스 사용자
    group       haproxy                  # harpoxy 서비스 그룹
    daemon                               # background로 실행될 수 있도록 설정

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats



#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults                                 # front, back, listen에 관련 설정 부분
    mode                    http         # http 프로토콜을 사용하는 로드벨런싱 모드
    log                     global       # 로그는 global에 설정한 방법으로 사용
    option                  httplog      # 기본 Log는 SIP, DIP와 Name만 표기됨, 해당 옵션을 사용하면 디테일하게 Log 표시
    option                  dontlognull  # Log 비대화 방지 -> Probe(정찰, 스캔과 같은 불필요한 기록을 HAProxy Log 기록 X
    option http-server-close             # 클라이언트와 리얼 서버 연결 종료시, 디폴트로 유휴 대기하지 않고, 서버에서 Handshake를 종료
                                         # 더 빠른 새로운 세션을 준비할 수 있도록 해줌
                                         # 디폴트 옵션에 선언되어 있어도, 인스턴스 별로 no 옵션으로 제외처리 가능
    option forwardfor       except 127.0.0.0/8     # 서버에 대한 응답을 HAProxy가 받기 때문에(VIP), 리얼 서버 IP를 HTTP 헤더에 표기하는 옵션
    option                  redispatch   # mode HTTP에서 Cookie에 지정된 Real 서버가 다운되면, 외부 클라이언트가 쿠키를 플로시하기 전에 서비스에 문제 발생 가능
                                         # redispatch 옵션을 통해 프로시 지속성을 무시하고 쿠키, 세션 재분재를 실행 -> retries값이 0보다 커야함
    retries                 3            # redispatch 횟수 결정
    timeout http-request    10s          # Request시의 헤더에만 적용. Dos 방어를 위해, HTTP 요청 타임 아웃시간 설정 -> 클라이언트의 연결 타임아웃과는 관계 X, HAProxy의 옵션
    timeout queue           1m           # 서버의 maxconn에 도달시, 무한정 보류 상태로 두지 않고 HTTP 503 응답을 보내면서 연결을 버리기까지의 시간
    timeout connect         10s          # TCP 패킷 손실을 막기 위한 Real 서버로의 연결 최대 지연시간 설정 -> Backend에 적용, 전역에도 적용 가능
    timeout client          1m           # 외부 클라이언트의 요청이나 데이터와의 연결 최대 시 ->  http-request가 선행, 서버 안정성에 기여
    timeout server          1m           # 서버가 데이터를 승인하거나, 전송해야 할 때의 연결 최대 시간
    timeout http-keep-alive 10s          # 클라이언트의 요청에 따른 응답 전송 후, 다음 요청까지의 대기 시간 -> http-request가 선행 필수
    timeout check           10s          # timeout server와 동일하거나 작은 값을 가져야함
    maxconn                 3000         # 프로세스당 최대 연결 개수

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend http
    bind: *:80                               # haproxy 구동시 사용할 포트를 지정 -> 클라이언트의 연결을 받는 부분(WAF 기능과 유사)
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    use_backend static          if url_static    # ACL에서 정의한 style들을 backend static으로 전송
    default_backend             static           # 아래 backend 중에서 static 부분을 사용 -> 미리 여러개 설정해놓고 선택


#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static                                   # 실제 접속시 로드밸런싱하는 서버
    balance     roundrobin                       # roundrobin은 무조건 한번씩 번갈아 접속시키는 방식 -> source 값을 이용
    server      static 192.168.100.201:80 check  # 포워딩할 서버 IP와 포트 설정
    server      static 192.168.100.202:80 check  # 포워딩할 서버 IP와 포트 설정

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
    server  app1 127.0.0.1:5001 check
    server  app2 127.0.0.1:5002 check
    server  app3 127.0.0.1:5003 check
    server  app4 127.0.0.1:5004 check


#listen                                          # 프론트/백엔드 연결의 포트/옵션등 정의 -> TCP 제어나 Proxy에 주로 사용
#listen stats                                    # "stats"라는 이름으로 listen 지정
#    bind *:9000                                 # 접속 포트 지정
#    stats enable
#    stats realm Haproxy Statistics              # 브라우저 타이틀
#    stats uri /haproxy_stats                    # stat 를 제공할 URI
#    #stats auth Username:Password               # 인증이 필요하면 추가

5.2. haproxy.conf 파일에 넣은 내용 → 간단하게 적용

global
  log  127.0.0.1 local2

  chroot  /var/lib/haproxy
  pidfile /var/run/haproxy.pid
  maxconn 4000
  daemon

defaults
    mode  http
    log  global
    option  httplog
    option  dontlognull
    option http-server-close
    option forwardfor  except 127.0.0.0/8
    option  redispatch
    retries  3
    timeout http-request  10s
    timeout queue  1m
    timeout connect  10s
    timeout client  1m
    timeout server  1m
    timeout http-keep-alive  10s
    timeout check  10s
    maxconn  3000

frontend http
    bind *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    default_backend  back_server


backend back_server
    balance  roundrobin
    server  web1 192.168.100.201:80 check
    server  web2 192.168.100.202:80 check



6. HAproxy의 conf 파일에 문제 없는지 Check

  • haproxy.cfg 설정이 이상 없는지 확인
    $ haproxy -f /etc/haproxy/haproxy.cfg -c
    Configuration file is valid


7. 방화벽 해제(firewalld)

$ systemctl stop firewalld
$ systemctl disable firewalld



8. HAproxy 서버스를 원할하게 실행하기 실행을 위한 커널 파라미터 변경

8.1. net.ipv4.ip_forward = 1

  • Kernel이 패킷을 전달하게 하는 경우 사용
  • Keepalived가 네트워크 패킷을 실제 서버에 정상적으로 전달하려면 각 라우터 노드가 커널에서 IP Forward를 설정 필요

8.2. net.ipv4.ip_nonlocal_bind = 1

  • HAProxy 및 Keepalived의 로드밸런싱은 동시에 로컬이 아닌 IP 주소에 바인딩할 수 있어야함
  • 네트워크 인터페이스에 없는 주소로 바인딩할 수 있도록 해주는 커널
  • 네트워크 인터페이스가 지정된 정적 IP가 아닌 동적 IP를 바인딩할 수 있음
  • 해당 옵션이 비활성화 되어 있어도 서비스가 시작하면서 인터페이스에 특정 IP를 바인딩할 수 있으나 FailOver시 문제 발생

8.3. 커널 파라미터 적용

$ cat << EOF >> /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
EOF

# /etc/sysctl.conf 파일 확인
$ cat /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1

# /etc/sysctl.conf 파일 내용 적용
$ sysctl --system
* Applying /usr/lib/sysctl.d/00-system.conf ...
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
kernel.yama.ptrace_scope = 0
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
kernel.kptr_restrict = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
* Applying /etc/sysctl.conf ...
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1



9. 로그 설정

9.1. rsyslog 에 HAproxy 용 로그를 남기도록 설정 → /etc/rsyslog.d/haproxy.conf 파일 구성

$ vi /etc/rsyslog.d/haproxy.conf
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
$template Haproxy, "%msg%\n"

#rsyslog 에는 rsyslog 가 메세지를 수신한 시각 및 데몬 이름같은 추가적인 정보가 prepend 되므로, message 만 출력하는 템플릿 지정
# 이를 haproxy-info.log 에만 적용한다.
# 모든 haproxy 를 남기려면 다음을 주석해재, 단 access log 가 기록되므로, 양이 많다.
#local0.*   /var/log/haproxy/haproxy.log

# local0.=info 는 haproxy 에서 에러로 처리된 이벤트들만 기록하게 됨 (포맷 적용)
local0.=info    /var/log/haproxy/haproxy-info.log;Haproxy

# local0.notice 는 haproxy 가 재시작되는 경우와 같은 시스템 메세지를 기록하게됨 (포맷 미적용)
local0.notice   /var/log/haproxy/haproxy-allbutinfo.log

9.2. logroate에 HAproxy 설정을 추가 → /etc/logrotate.d/haproxy 파일 구성

  • haproxy는 재시작할 필요가 없으므로 rsyslog 를 재시작해줌

    $ vi /etc/logrotate.d/haproxy
    /var/log/haproxy/*log {
        daily
        rotate 90
        create 0644 nobody nobody
        missingok
        notifempty
        compress
        sharedscripts
        postrotate
            /bin/systemctl restart rsyslog.service > /dev/null 2>/dev/null || true
        endscript
    }
    
    # rsyslog 서비스 재시작
    $ systemctl restart rsyslog



10. HAproxy 서비스 시작

  • HAproxy 서비스 시작 및 영구 설정

    $ systemctl start haproxy
    $ systemctl enable haproxy
    
    $ systemctl status haproxy
    ● haproxy.service - HAProxy Load Balancer
       Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
       Active: active (running) since Sun 2021-08-01 15:32:34 KST; 5s ago
     Main PID: 1030 (haproxy-systemd)
       CGroup: /system.slice/haproxy.service
               ├─1030 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
               ├─1031 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
               └─1032 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds



11. Web 서버 2대(192.168.100.201, 192.168.100.202)에 nginx 설치 및 index.html 파일 변경

11.1. web1(192.168.100.201) 서버에 nginx 설치 및 index.html 파일 변경

# nginx 패키지 설치
$ yum install -y nginx

# nginx의 index.html 파일 내용 변경
$ vi /usr/share/nginx/html/index.html
hello~~~~
webser : web1
Bye

# nginx 시작
$ systemctl enable --now nginx

11.2. web1(192.168.100.202) 서버에 nginx 설치 및 index.html 파일 변경

# nginx 패키지 설치
$ yum install -y nginx

# nginx의 index.html 파일 내용 변경
$ vi /usr/share/nginx/html/index.html
hello~~~~
webser : web2
Bye

# nginx 시작
$ systemctl enable --now nginx



12. HAproxy 트래픽 테스트

  • harpoxy의 IP(192.168.100.101)으로 트래픽을 전달하면 backend에 있는 서버(192.168.100.201, 192.168.100.202)로 트래픽 전송

  • Round-Robin으로 설정하였기에 192.168.100.201과 192.168.100.202에 번갈아가면서 트래픽 전달

  • haproxy 트래픽 테스트는 해당 서버와 상관없는 192.168.100.10에서 진행

    $ while true; do curl 192.168.100.101; echo -e "\n"; sleep 3; done
    hello~~~~
    webser : web1
    Bye
    
    hello~~~~
    webser : web2
    Bye
    
    hello~~~~
    webser : web1
    Bye
    
    hello~~~~
    webser : web2
    Bye



13. HAProxy 어드민 페이지 설정

13.1. HAProxy의 상태 및 통계 제공 웹을 위한 설정

  • mode http → 통계 사이트는 http를 통해 접속
  • bind * :8020 → haproxy의 IP 에 8020 포트 접속
  • stats enable→ HAProy의 어드민 페이지를 stats로 칭하여 enable 표시함으로 사용함
  • stats auth root:hello→ HAProy의 어드민 페이지의 ID는 root, PW는 hello
  • stats uri /monitor → path를 /monitor로 지정
    # /etc/haproxy/haproxy.cfg 파일 가장 아래에 추가
    $ vi /etc/haproxy/haproxy.cfg
    listen monitor
      mode http
      bind *:8020
      stats enable
      stats auth root:hello
      stats uri /monitor

13.2. HAProxy.cfg 파일 검증 및 재시작

# 위 내용이 적합한지 검증
$ haproxy -f /etc/haproxy/haproxy.cfg -c
Configuration file is valid

$ systemctl restart haproxy

13.3. HAProxy monitor에 접속 → http://haproxy_IP:8020/monitor 접속

  • 로그인 후 monitor 화면 출력

14. 추가 HAproxy Kernel Parameter

14.1. 가장 중요한 Paramater

net.ipv4.ip_local_port_range = "1025 65534"
net.ipv4.tcp_max_syn_backlog = 100000
net.core.netdev_max_backlog = 100000
net.core.somaxconn = 65534
ipv4.tcp_rmem = "4096 16060 64060"
ipv4.tcp_wmem = "4096 16384 262144"

14.2. 작업량에 따라 조절

tcp_slow_start_after_idle = 0

14.3. iptables tuning

net.netfilter.nf_conntrack_max = 131072

14.4. HAproxy Kernel Parameter 사용시 주의 사항

  • conntrack이 잘못 구성되면 HAProxy가 최대 성능을 발휘 X
  • iptables가 활성화 되어 있으면 connection tracking 작업을 위해 iptables에 규칙이 없더라도 20%의 CPU를 소모

참고 URL : https://lascrea.tistory.com/213
참고 URL : https://findstar.pe.kr/2018/07/27/install-haproxy/
참고 URL : https://medium.com/@tamm_/%EA%B0%9C%EB%B0%9C-haproxy-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95-f4623815622
참고 URL : https://blog.develope.kr/2020/01/haproxy%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%A1%9C%EB%93%9C-%EB%B0%B8%EB%9F%B0%EC%8B%B1-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0-2-haproxy-%EC%84%A4%EC%B9%98-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0/


  • 도메인 이름을 사용하기 위해서는 도메인 이름을 관리하는 레지스트리의 레지스트리 데이터베이스에 등록 필요
  • 현재 .kr이나 .com와 .net 등 주요한 TLD는 레지스트리·레지스트라 모델(Registry·Registrar model)을 등록 구조로 채택

1. 레지스트리·레지스트라 모델(Registry·Registrar model)

1.1. 레지스트리·레지스트라 모델(Registry·Registrar model) 분리

  • 레지스트리와 레지스트라 모델은 도메인 이름의 등록 관리를 아래 두가지 역할로 분리하고 있음
    1. 레지스트리 → 도메인 이름을 일원화 관리
    2. 레지스트라 → 도메인 이름의 등록자로부터 신청을 중개

1.2. 레지스트리·레지스트라 모델(Registry·Registrar model) 역할을 분리하는 이유

  1. 도메인 이름 등록에서 등록될 도메인 이름을 고유하게 하면서 가격이나 서비스의 다양성을 확보하기 위함
  2. 하나의 TLD에 대해서 레지스트리는 하나이지만 레지스트라는 보통 여럿이 존재함
  3. 각 레지스트라는 획일적인 서비스가 아닌 다양한 서비스를 등록자에게 제공할 수 있음 → 레지스트라는 독자적인 서비스나 가격 설정이 가능하고, 등록자는 자신에게 맞는 레지스트라를 고를 수 있음

1.3. 레지스트리·레지스트라 모델(Registry·Registrar model)에서 리셀러(reseller)

  1. 레지스트라를 통해서 등록한 도메인 이름을 다른 등록자에게 재판매하는 것을 리셀러(reseller)라고 함
  2. 리셀러는 레지스트라와 등록자 사이에서 도메인 이름의 등록에 관한 각종 신청을 중개함
  3. 리셀러는 레지스트리와의 계약 관계가 없으며 해당 도메인 이름을 취급하는 레지스트라와 계약을 맺고, 등록자로부터 레지스트라에게 도메인 이름의 등록을 중개함
  4. 등록자 입장에서 볼때 도메인 이름의 등록을 접수하는 사업자가 레지스트라인 경우도 있고, 리셀러인 경우도 있음

1.4. 레지스트리·레지스트라 모델(Registry·Registrar model)에서 역할의 분리


2. 레지스트리(Registry)

  • 레지스트리(Registry)는 등록된 도메인명의 데이터베이스를 유지 관리하는 기관
  • 같은 도메인명이 이중 등록되지 않도록 레지스트리는 데이터베이스를 일원적으로 관리
  • 최상위 도메인(TLD) 별로 레지스트리는 하나만 존재하며, 하나의 레지스트리가 복수의 최상위 도메인을 관리하기도 함
  • 레지스트리(Registry) 예시
    • .com의 레지스트리는 VeriSign → VeriSign은 .com 이외에 .net도 관리
    • 레지스트리는 등록된 도메인명이 인터넷 상에서 접속될 수 있도록 최상위 도메인(TLD)의 도메인 네임 서버(DNS)를 운용하고 있음


3. 레지스트라(Registrar)

  • 레지스트라는 도메인 네임 등록 대행 업체
  • 레지스트라는 등록자로부터 도메인 네임의 등록 신청을 접수하고, 등록 데이터를 레지스트리의 데이터베이스에 등록함
  • 최상위 도메인 당 하나만 존재하는 레지스트리와 달리, 등록 서비스를 제공하는 레지스트라는 레지스트리와의 계약 하에 복수 존재 가능
  • 도메인 등록•관리 비용은 레지스트라에 따라 차이가 있음
  • 레지스트라로 인정되기 위해서는 국제 인터넷 주소 관리 기구(ICANN)에 의한 심사에 합격할 필요가 있음
  • 아래 레지스트라(Registrar)의 역할 정리

3.1. 등록자로부터 등록 신청 접수

  • 도메인 이름의 등록자로부터 등록 신청을 접수함

3.2. 레지스트리 데이터베이스에 등록 의뢰

  • 등록자의 신청에 따라 레지스트리에게 도메인 이름의 등록을 의뢰
  • 등록 의뢰 결과를 등록자에게 알려줌

3.3. Whois 서비스 제공

  • 자신이 취급하는 도메인 이름에 관한 Whois 서비스를 제공

3.4. 등록자 정보 관리

  • 도메인 이름의 등록을 신청한 등록자의 정보를 관리함
  • 레지스트리와 레지스트라의 역할 분담은 TLD의 종류에 따라 달라짐
  • 예시)
    • KR 도메인 이름에서 Whois 서비스는 레지스트리만이 제공
    • 등록 정보를 관리하는 책임의 범위도 KR 도메인 이름과 gTLD가 서로 다름


4. 리셀러(Reseller)

  • 리셀러는 레지스트라를 경유하여 도메인 등록 업무를 대행하는 업자를 말함
  • 리셀러는 SRS(Shared Registry System)이라는 도메인 관리 시스템의 접속 권한 없음
  • 리셀러는 반드시 레지스트라를 경유하여 도메인을 관리하게됨


5. ICANN(국제 인터넷 주소 관리 기구)

  • ICANN은 The Internet Corporation for Assigned Names and Numbers의 약자
  • ICANN은 국제 인터넷 주소 관리 기구를 의미
  • 인터넷 주소 체제(DNS)의 효율적인 관리를 목적으로 설립된 비영리 기관 → 인터넷 도메인 관리와 정책을 결정하는 도메인 관련 국제 최고 기구


6. 관계 정리 : ICANN → 레지스트리 → 레지스트라 → 리셀러


  • 인터넷은 전체를 집중 관리하지 않는 분산 관리가 기본 → DNS도 계층화와 위임을 통해서 각 조직에 의한 분산 관리를 실현하기 위한 구조 중 하나
  • 인터넷에 연결된 호스트를 식별하기 위한 IP 주소(번호)나 도메인 이름(이름)과 같은 식별자는 예외적으로, 이용자가 혼란하지 않도록 통일되고 일원화된 관리를 해야함
  • 레지스트리(registry)는 인터넷상의 번호나 이름을 할당하고 등록하여, IP와 도메인을 이용자가 혼란하지 않도록 통일되고 일원화된 관리하는 조직
  • 레지스트리와 그 관계자에 의한 도메인 이름의 등록 관리 구조와 세계적인 관리 체계를 설명

1. 레지스트리 오퍼레이터의 2가지 의미

  • 식별자를 할당하고 등록 관리를 하는 레지스트리 오퍼레이터 → DNS에서 레지스트리 오퍼레이터를 레지스트리라고 함
  • 레지스트리 오퍼레이터가 취급하는 등록대장인 레지스트리 데이터 베이스


2. IP 주소와 도메인 이름 관리의 차이

  • IP 주소와 도메인 이름은 할당 및 등록 관리에 대한 처리가 다름

2.1. IP 주소

  • 한정된 자원을 인터넷 전체에서 공유하기 때문에, 이용 효율이나 공평한 할당과 같은 점을 고려해 세계적으로 일관성 있는 관리가 필요
  • 공평한 IP 관리를 하기 위해서, IP 주소 레지스트리는 규칙을 정하거나 레지스트리 간의 조정을 담당

2.2. 도메인 이름

  • 하나의 네임 스페이스를 TLD마다 분할하고, 각 TLD의 특색에 맞게 이용자의 다양한 요구에 부합하는 서비스를 운용할 수 있다는 유연성을 가짐
  • 도메인 이름은 이용자에게 친근한 단체명, 서비스명, 상품명을 연상시키기 때문에 등록, 이용 중에 발생한 트러블, 분쟁을 해결하기 위한 구조도 필요


3. 레지스트리의 역할

  • 도메인 이름을 사용할 수 있도록 하기 위해서는 레지스트리에게 '이 도메인 이름을 사용하고 싶다'라는 등록 신청함
  • 신청을 접수한 레지스트리는 그 내용이 등록 요건에 부합하는지를 심사 및 확인하고 데이터베이스에 등록
  • 위 과정을 거쳐서 신청자는 도메인 이름을 사용할 권리를 얻게 됨
  • 등록한 도메인 이름에는 만료일이 설정되며, 수명 주기(life cycle)에 따라 운용해야합니다.
  • 레지스트리는 신규 등록 외에, 등록자의 신청에 따라서 이미 등록된 도메인 이름의 등록 정보 갱신, 만료일 갱신, 삭제 등을 하면서 도메인 이름을 관리
  • 도메인 이름의 수명 주기란
    • 도메인 이름은 한번 등록하면 영원히 사용할 수 잇는 것이 아니라 만료일이 존재합니다.
    • 만료일이 지난 도메인 이름은 일정 기간 후에 '삭제'로 취급되며, 삭제된 도메인 이름은 다시 등록할 수 있게 됩니다.
    • KR 도메인 이름의 등록부터 삭제까지 수명 주기에 대한 추가 정보 → 도메인 주소에서 생명 주기(Life Cycle)란


4. 레지스트리의 주된 역할 여섯가지

4.1. 레지스트리 데이터베이스의 운영 관리

  • 등록 정보를 축적하고 관리하는 등록 대장인 '레지스트리 데이터베이스'를 운용
  • 등록 정보란, 도메인 이름을 등록하기 위해 필요한 개인의 이름, 조직명, 연락처와 같은 정보

4.2. 정책에 따른 등록 규칙의 제정

  • 레지스트리는 자신이 등록 관리하는 도메인 이름의 정책을 정함
  • 정책을 실현하기 위한 등록 규칙과 세칙을 정하고 이용자에게 알려줌

4.3. 등록 신청 접수

  • 레지스트리는 등록자로부터 도메인 이름의 등록 신청을 접수함
  • 신청된 도메인 이름을 규칙에 따라 심사하고 접수한 정보를 레지스트리 데이터베이스에 등록함

4.4. Whois 서비스 제공

  • 레지스트리는 자신이 관리하는 도메인 이름의 정보를 Whois 서비스로 제공
  • Whois의 자세한 자료 → WHOIS 서버란

4.5. 네임 서버 운용

  • 관리 대상인 도메인 이름을 인터넷에서 이용할 수 있도록 하기 위한 네임 서버를 관리 및 운용함
  • 레지스트리의 네임 서버는 등록자가 등록한 위임 정보를 관리

4.6. 정보 전달 및 교육 활동

  • 인터넷 전체를 원활하게 운용하기 위해 많은 레지스트리가 인터넷에 관한 정책, 거버넌스, 기술 등 각 분야의 정보를 전달하거나 교육 활동을 하고 있음


5. 레지스트리와 TLD의 관계

  • TLD마다 레지스트리가 존재하며, 각 레지스트리가 TLD를 관리하고 관리 정책이나 등록 규칙을 정함
  • TLD의 두가지 종류
    1. 국각나 지역마다 할당되는 도메인 : ccTLD(Country Code Top Level Domain)
    2. 국가나 지역에 상관없는 도메인 : gTLD(Generic Top Level Domain)

5.1. ccTLD

  • 문자열(라벨)에는 원칙적으로 ISO(국제 표준화 기구)의 ISO 3166-1로 규정된 두 글자의 국가코드가 사용됨
  • 한국에는 국가코드 'KR'이 할당
  • ccTLD가 두 글자가 된 이유
    • ISO 3166-1에는 알파벳 두 글자를 사용한 'alpha-2', 알파벳 세 글자를 사용한 'alpha-3', 숫자 세글자를 사용한 'numeric-3'가 규정
    • ccTLD를 정할 때 세 글자 TLD인 '.com'과 '.net' 등은 이미 사용
    • 숫자는 IP 주소와 혼돌할 우려가 있어서 채택되지 못하고 알파벳 두 글자를 사용한 'alpha-2'가 채택

5.2. gTLD

  • gTLD는 등록하는데 특별한 제한이 없는 것과 일정 요건이 필요한 것 2가지가 있음
  • '.com'과 '.net'을 등록하는 데 특별한 제한이 없는 gTLD임
  • '.edu'나 '.gov'와 같은 gTLD는 등록 제한이 있으며, 등록 가능한 대상은 미국의 교육기관이나 정부 기관으로 한정됨
  • gTLD의 변천
    • 인터넷에 도메인 이름과 DNS가 도임된 1985년에 창설된 gTLD는 .com, .edu, .gov, .mil, .net, .org로 여섯 개가 있음
    • 이후 1988년에 국제단체가 사용하는 .int가 도임되어 일곱 개의 gTLD가 운영됨
    • ARPANET에서 기술을 이전하기 위한 용도로 .arpa도 추가 생성 → .arpa는 인프라스트럭처 도메인으로 전환되어 IP 주소의 역방향 등에서 사용
    • 1990년대 후반부터 인터넷의 급속한 발전과 상용으로 새로운 TLD 도입이 요구
    • 많은 gTLD가 추가되면서 현재 1,200개가 넘는 gTLD가 운영되고 있음
  • 새로운 gTLD
    • 커뮤니티 TLD(Community-based TLD 또는 Community TLD)
    • 특정 커뮤니티나 그룹의 이용을 전체로 한 gTLD
    • 예를 들어 제약 업계를 대상으로 한 '.pharmacy'나 은행 업계를 대상으로 한 '.bank'가 있음
  • 지리명 TLD(Geographical TLD 또는 Geographic names TLD)
    • 각국의 도시, 지역명 등을 대상으로 한 gTLD
    • 지리명 TLD
  • 브랜드 TLD(Brand TLD)
    • 기업명이나 조직명, 상표 등의 문자열을 사용하는 gTLD

5.3. TLD의 예시와 레지스트리


  • 도메인 또한 한 번 등록하면 영원히 내 것이 되는 것이 아니라, ‘등록 기간’에 따라 만료일이 정해져 있음
  • 만료일에 가까워졌을 때 기간을 ‘연장’을 하지 않으면 도메인이 곧 삭제됨
  • 삭제된 도메인은 다른 사람에 의해 다시 등록되어 새 생명을 얻을 수 있음
  • 도메인의 등록→연장→삭제→방출→재등록에 이르는 순환 과정을 생물의 생존 주기에 빗대어 ‘Domain Name Life Cycle’이라 함

1. COM, NET으로 대표되는 ‘gTLD’의 등록 주기


1.1. 등록 기간

  • 거의 모든 Registrar의 gTLD 등록 기간은 1~10년
  • 도메인 등록 기간이 끝나기 전에 연장을 해야 지속적으로 보유 혹은 사용 가능
  • 만기일(Expiration Date)이 돌아오기 전에 도메인을 지속적으로 연장을 한다면 사실상 도메인의 등록 기간은 영구적이라 볼 수 있음

1.2. 신규 등록 취소 가능 기간 (5일)

  • Registrar에서 Registry로 신규 등록 취소 요청을 하고 환불을 받을 수 있는 기간
  • 대부분의 Registrar는 신규 취소 기간을 제공하지 않음
  • 대표적인 이유는 어떤 사용자가 다량으로 도메인을 등록한 후, 5일의 기간 동안 트래픽이 좋은 극히 일부 도메인을 제외하고 나머지 도메인은 취소하여 환불을 받아내는 ‘Domain Tasting’ 행위 때문임
  • 무엇보다 가장 큰 문제는 다른 사용자가 도메인을 등록할 수 있는 기회를 박탈하게 된다는 점

1.3. Auto-Renew Grace Period (만기 후 추가 연장 가능 기간, 0~45일)

  • 만기일 이후 자신의 의사에 반하여 사이트가 중단되거나 도메인이 삭제되는 일을 방지하기 위하여 유예 기간(45일)을 둠
  • 만기 후 추가 연장 가능 기간을 'Auto-Renew Grace Period'라고 함

1.4. Redemption Grace Period (2차 추가 연장 기간, 30일)

  • '등록 취소 가능 기간' 혹은 'Auto-Renew Grace Period' 두 기간에도 연장을 하지 않아 Registrar가 삭제한 도메인에 대하여 2차로 연장을 할 수 있도록 부여된 기간(30일)을 의미
  • 국내에서는 주로 ‘도메인 복구(Restore) 기간’
  • 이미 한번의 추가 기회가 주어졌음에도 불구하고 연장을 하지 않았기 때문에 복구를 통한 연장은 훨씬 비싼 비용이 부과됨

1.5. Pending Delete (방출 대기 기간, 5일)

  • 복구 기간에도 연장되지 않은 도메인은 5일 후에 Registry에서 누구나 등록할 수 있도록 방출하게 되는데, 이 5일의 대기 기간을 ‘Pending Delete’라 함
  • Pending Delete가 지난 후, 도메인은 다시 ‘등록 가능한’ 상태가 됨

1.6. 방출(등록 가능)

  • 이전에 사용하던 도메인이 남아있어서 그것을 누군가가 다시 등록하는 개념이 아니라, 아무에게도 등록되지 않은 ‘존재하지 않는’ 도메인을 새로이 등록하는 개념
  • gTLD는 이러한 주기를 거쳐 생을 마감하고, 새 생명을 얻음


2. KR로 대표되는 ‘ccTLD’의 등록 주기


2.1. 등록 기간

  • KR 도메인의 등록 주기는 1~10년으로 gTLD의 등록 주기와 동일

2.2. 신규 등록 취소 가능 기간 (7일)

  • 도메인 신규 등록을 취소하고 환불을 받기 위해서는 공휴일 여부와 상관없이 등록일로부터 7일 내 말소 요청을 해야함

2. 3. 추가 연장 가능 기간 (1개월)

  • KR 도메인은 만기일이 지나면 단 1개월의 추가 연장 기간만 있음
  • Pending Delete(방출 대기 기간)도 운영하지 않기 때문에 만기일이 속해 있는 월에 따라 만기일 후 30일, 31일이 지난 다음 날 오전에 누구나 등록할 수 있도록 방출됨
  • 추가 연장 기간(1개월)만 부여한 후, 누구나 등록할 수 있도록 방출
  • 사용자가 도메인을 등록한 후 연장하지 않는다면, 같은 날, 같은 기간으로 등록된 KR 도메인의 방출일은 모두 동일

참고 URL : https://library.gabia.com/domain-lifecycle/


  • 도메인 이름 등록 구조에서 최상위에 위치는 ICANN 단체임 → 전세계에 있는 IP주소를 관리함과 동시에 Root 네임서버 관리자 역할을 함
  • ICANN은 a.root-servers.net ~ m.root-server.net 이라고 하는 서버들을 관리 → 성능좋은 수많은 서버들은 전세계에 흩어져 웹 통신이 가능하도록 역할을 함
  • Top-level 도메인을 관리하는 등록소가 있음
  • 등록자가 도메인을 등록하는 작업을 대행해주는 등록대행자가 있음

 

1. Root 네임서버에 세팅

  • Root DNS 서버는 전세계의 Top-level DNS 서버의 주소를 기억
  • "com NS a.gtld-servers.net"의 의미는 "com 이라고 하는 Top-level 도메인의 네임서버는 a.gtld-servers.net 이라는 주소에 존재한다"
  • Root 네임서버는 .com을 누가(Top-level DNS 서버) 관리하는 것인지 알게됨

 

2. Top-level DNS에 세팅

  • Top-level DNS에 서버도 등록자의 네임서버를 알고 있어야 함
  • "hippotest.com NS a.iana-servers.net"의 의미는 "hippotest.com 이라고 하는 등록자의 네임서버(nameserver)는 a.iana-servers.net 이라는 주소에 존재한다"

 

3. 등록자의 네임서버(nameserver) 세팅

  • 등록자의 네임서버는 등록자의 IP주소를 알고 있어야 함
  • 등록자는 자신의 IP주소 118.222.88.11를 "hippotest.com A 118.222.88.11"의 형식으로 네임서버(nameserver)에 IP 주소를 알려줌
  • "hippotest.com A 118.222.88.11"의 의미는 "hippotest.com의 주소는 118.222.88.11입니다"

 

4. 도메인 이름 등록 프로세스 간략화

 

 

5. 도메인 이름 등록 프로세스

1. 첫번째 작업

  • hippo 서버를 운영하고 싶은 운영자는 스스로 서버 1대를 마련해서 네임서버(nameserver)를 설치
  • 네임서버(nameserver)를 설치한 컴퓨터를 a.iana-servers.net이라고 간주하고, 서버에 도메인을 세팅
  • 네임서버(nameserver)는 운영자가 직접 구축할 수도 있지만 대부분의 경우 등록대행자(등록대행업체 : 카페24, 닷홈 등)가 네임서버를 제공
  • 무료로 제공되는 네임서버(nameserver)도 이용 가능

 

2. 두번째 작업

  • hippo 서버는 hippotest.com을 쓰고 싶다고 등록대행자에게 요청 → 수수료를 지불
  • 수수료로 도메인 등록 체계가 운영
  • 요청하는 과정에서 "hippotest.com NS a.iana-servers.net"이라는 정보를 등록대행자에 알려주게 됨

 

3. 세번째 작업

  • 등록대행자는 등록소에 hippotest.com을 등록하는것이 가능한지 요청
  • "hippotest.com NS a.iana-servers.net"이라는 정보를 등록소에 알려줌

 

4. 네번째 작업

  • 등록소는 hippotest.com이 등록가능한지 여부를 조회하고 등록가능하다면 계약된 기간동안 해당 도메인이 사용가능하다는 것을 알려줌
  • hippotest.com의 소유권을 등록대행자를 통해서 등록자가 인식할 수 있도록 통보 → 소유권이 없는 다른 사람이 사용하지 못하도록 설정 필요
  • "hippotest.com NS a.iana-servers.net"이라는 정보를 등록소가 관리하는 Top-level DNS 서버에 저장 → 등록자의 네임서버를 알게됨

 

5. 다섯번째 작업

  • 클라이언트 컴퓨터는 인터넷에 접속하자마자 자신이 지정한 또는 통신사에서 지정한 DNS 서버에 자동으로 접속하게 됨

 

6. 여섯번째 작업

  • hippotest.com의 IP 주소를 Root DNS 서버에 요청
  • Root DNS 서버는 .com을 관리하는 Top-level DNS 서버의 주소인 a.gtld-servers.net로 가보라고 알려줌

 

7. 일곱번째 작업

  • Top-level DNS 서버의 주소인 a.gtld-servers.net에 hippotest.com의 IP주소를 요청
  • Top-level DNS 서버는 hippo 네임서버 주소인 a.iana-servers.net으로 가보라고 알려줌

 

8. 여덟번째 작업

  • hippotest.com 네임서버 주소인 a.iana-servers.net에 hippotest.com의 IP주소를 요청
  • hippotest.com 네임서버는 "hippotest.com의 IP 주소는 118.222.88.11입니다."라고 클라이언트 컴퓨터의 지정된 DNS서버로 알려줌

 

9. 아홉번째 작업

  • 지정한 DNS 서버는 hippotest.com의 IP 주소를 알게됨 → 전달받은 서버 IP인 118.222.88.11를 통해 hippotest.com 웹사이트와 통신 가능

 

참고 URL : https://boojafactory.tistory.com/172

 

  • DNS 서버의 기본 동작은 클라이언트에서 질의 메시지를 받은 내용에 따라서 등록 정보를 회신하는 것
  • DNS에서 도메인 네임(또는, DNS Zone)과 관련된 개별 정보 항목을 갖는 레코드
  • DNS는 분산된 DNS 네임서버 내 자원 레코드의 집합

질의 메시지에는 아래와 같은 세 가지 정보가 포함


DNS RR(Resource Records) 종류


DNS 서버는 본질적으로 데이터베이스 서버의 하나 유형

  • 데이터베이스 항목을 자원레코드(RR)라고 하며 아래는 예시

DNS 서버에 MX 타입 질의 예시

  • IP 주소를 문의할 때는 A라는 타입을 쓰지만 메일 보낼 곳을 질의할 때는 MX(Mail eXchange)라는 타입을 사용함
  • webmaster@cyber.co.kr이라는 메일 주소가 있고, 보낼 곳을 알아야 할 경우는 @ 뒤에 있는 이름이 메일을 보낼 곳이 되므로 이름을 문의
    1. 문의 내용
    2. 이름 = cyber.co.kr
    3. 클래스 = IN
    4. 타입 = MX
  • DNS 서버는 10 mail.cyber.co.kr이라는 내용을 클라이언트로 회신
  • 타입이 MX인 경우 회신할 항목 2가지
    1. 우선순위(10)와 메일 서버이름(mail.cyber.co.kr)
    2. mail.cyber.co.kr이라는 메일 서버의 IP 주소도 함께 회신해야 함

  • 이용자의 요구에 따라 도메인 이름에 대응하는 IP 주소를 찾아내는 것을 name resolution이라고 함
  • name resolution이라는 구조는 DNS의 중요한 기본 기능

1. 질의와 응답

  • name resolution의 기본은 질의와 응답
  • 질의와 응답을 통한 주고받는 정보를 알고 싶은 사람과 정보를 제공하는 사람 사이에서 발생

1.1. 질의와 응답에 대한 3가지 약속이 있음

  1. 질의와 응답은 항상 1대 1로 대응함
    • 질의에 대응하지 않는 응답이 오거나, 한 개의 질의에 두 개의 응답이 오는 일은 없음
    • DNS에 www.foo.bar 도메인에 대한 IP 질의
  1. 정보를 알고 싶은 사람은 알고 싶은 정보의 이름(도메인 이름)과 종류(타입)를 지정
  1. 정보를 제공하는 사람은 받은 질의에 대해 자신이 알고 있는 정보를 응답
    • www.foo.bar에 IP는 1.2.3.5으로 질의한 클라이언트에 응답

2. name resolution의 작동

2.1. name resolution의 네 가지 포인트

  1. A가 보내는 질의는 항상 같은 내용임
  1. A가 보낸 질의를 받은 네임 서버는 자신이 알고 있는 정보를 응답
    • 네임 서버가 도메인 이름을 다른 네임 서버에게 위임하고 있을 때는 위임처(자식)의 네임 서버 정보를 응답함
    • 네임 서버가 도메인 이름의 정보를 가지고 있을 때는 가지고 있는 정보를 응답
  1. A는 응답이 네임 서버 정보에 관한 것인지 원하는 응답인지에 따라 행동을 변경
  1. 네임 서버 정보를 받았을 때, A는 정보에 적힌 네임 서버에게 질의함

2.2. name resolution의 작동 예시

  1. 클라이언트가 www.foo.bar에 접속 시도
    • 클라이언트는 www.foo.bar의 IP 주소를 알 수 없기에 DNS 확인 필요
  1. 루트(root) 질의 및 응답
    • A는 계층 구조의 정점인 루트의 네임서버로 알고 싶은 정보의 이름과 종류(www.foo.bar의 IP)를 질의함
    • 루트는 bar을 위임하고 있기 때문에 위임처인 bar의 네임 서버 정보(ns.bar.)를 응답
  1. .bar. 질의 및 응답

    • 루트로 부터 받은 응답에서 아래 두 가지를 알 수 있음
      • 루트는 bar를 위임하고 있음
      • 위임처의 네임 서버는 ns.bar.임
    • 루트로 부터 받은 정보를 사용해 bar의 네임 서버로 이름과 종류(www.foo.bar의 IP)를 질의함
    • bar은 foo.bar을 위임하고 있기 때문에 위임처인 foo.bar의 네임 서버 정보(ns.foo.bar,)를 응답
  2. foo.bar. 질의 및 응답

    • bar.로 부터 받은 응답에서 아래 두 가지를 알 수 있음
      • bar는 foo.bar를 위임하고 있음
      • 위임처의 네임 서버는 ns.foo.bar.임
    • bar.로 부터 받은 정보를 사용해 foo.bar.의 네임 서버로 이름과 종류(www.foo.bar의 IP)를 질의함
    • foo.bar 네임 서버는 www.foo.bar의 IP 주소를 알고 있기 때문에 IP 주소를 응답
    • A는 www.foo.bar의 IP 주소(1.2.3.4)를 얻을 수 있으며 name resolution이 종료됨
  1. 클라이언트에 www.foo.bar의 IP 응답

3. name resolution을 위해 필요한 것

3.1. 부모가 응답하는 자식의 네임 서버 정보 → '위임 정보'

  • 어떤 도메인에 서브 도메인을 만들고, 서브 도메인을 다른 사람에게 위임하면 위임한 쪽(부모)와 위임 받는 쪽(자식)은 부모-자식 관계가 됨
  • 네임 서버가 응답하는 위임처(자식)의 네임 서버 정보를 가지고 계층 구조를 따라감
  • 계층 구조를 따라갈 수 있도록 하기 위해서 위임자(부모)가 응답하는 위임처(자식)의 네임 서버 정보를 위임 정보라고 함

3.2. 위임 정보의 등록

  • foo.bar(자식)은 bar(부모)에게 "foo.bar.을 관리하고 있는 'ns.foo.bar.'이라는 네임 서버를 bar.의 네임 서버에 등록해 주세요"라고 의뢰함
  • 의뢰를 받아 bar은 foo.bar.의 네임 서버 정보(ns.food.bar)를 자신의 네임 서버(ns.bar)에 등록함
  • bar의 네임 서버는 www.foo.bar에 대한 질의가 오면 위임 정보로서 foo.bar의 네임 서버 정보(ns.foo.bar)를 응답함 → 부모가 응답하는 위임 정보는 자식이 등록한 네임 서버 정보
  • 자식이 잘못된 정보를 등록하면 부모는 잘못된 위임 정보를 응답하게 되고 name resolution를 할 수 없게 됨
  • name resolution를 하는 사람이 계층 구조를 따라갈 수 있게 하기 위해서는 아래 두가지가 필요
  • 자식이 부모에게 올바른 네임 서버 정보를 등록함
  • 부모가 자식으로부터 받은 네임 서버 정볼르 위임 정보로서 정확하게 응답함


4. name resolution에서 위임의 중요성

  • DNS의 name resolution는 부모가 자식에게 위임하여 만들어지는 계층 구조를 따라가는 것으로 이루어짐
  • name resolution의 구조가 가져다 주는 장점

4.1. 존(zone)마다 분산 관리를 실현할 수 있음

  • 계층화와 위임에 의해 관리하는 범위를 분산할 수 있음
  • 계층 구조를 도입해서 각 계층의 관리를 위임함으로써 위임자(부모)는 위임처(자식)의 위임 정보만 관리하면 되고, 위임처(자식)는 자신이 위임받은 부분의 계층을 관리하면 됨
  • DNS에서는 위임에 의해 관리하게 된 범위를 존(zone)이라함 → 계층화와 위임에 의해 존마다 분산 관리를 실현할 수 있음

4.2. 존(zone)을 어떻게 다룰지는 그 존의 관리자가 정할 수 있음

  • 위임된 존(zone)은 위임처에서 관리함
  • 각 존(zone)의 관리 정책을 각 존(zone)의 관리자가 정할 수 있음
  • 예를 들면, KR존에서는 레지스트리인 KISA가 정책을 정하고 있음
  • KR 정책의 예시
    • 등록자는 한국에 주소를 갖는 조직이나 개인일 것
    • 한글 도메인 이름으로 등록 가능한 라벨은 한글, 숫자, 영문자를 사용할 수 있으며 반드시 한글을 포함할 것

4.3. 어떤 존(zone)에 트러블이 발생해도 그 영향 범위를 국소화할 수 있음

  • 어떤 존(zone)에 트러블이 발생했을 때, 그 존(zone)에만 영향이 미치며 다른 존(zone)에는 영향이 미치지 않음
  • 예를 들면, KR의 네임 서버가 응답하지 않아 name resolution를 하지 못하게 되었을 때는 KR과 그 서브 도메인에만 영향을 미치며, KR과 같은 계층에 있는 com이나 net 그리고 그 서브 도메인에는 영향이 미지지 않음

  • Ansible Vault는 패스워드, 키와 같은 보안에 민감한 파일들을 encryption / decryption 해주는 기능을 가짐(암호화)
  • Ansible-Vault는 변수와 파일을 암호화하여 플레이북이나 role에서 비밀번호. 키와 같은 민감한 콘텐츠를 보호 가능
  • Ansible을 이용할 때 해킹이나, 유출로 인해 서버 정보가 외부로 나갈 수 있음
  • Ansible Vault를 통해 민감한 정보를 평문이 아니라 암호화된 파일로 관리하면 해킹당해도 문제 X
  • SSH 개인 및 공개 키, 암호 및 SSL 인증서도 암호화된 파일로 관리하여 권한 없는 사람이 권한을 얻는 것을 방지
  • Ansible Vault를 이용하면 Ansbile에서 사용하는 모든 구조화된 데이터 파일을 암호화 가능
  • Ansible Vault는 변수 또는 전체 파일 및 YAML 플레이 북을 암호화 → 파일을 암호화하고 복호화 할 때 동일한 암호를 요구

1. Ansible-Vault 설치

  • Ansible을 설치하면 Ansible-vault도 함께 설치됨

  • 암호화 알고리즘 : AES256

    $ ansible-vault -h
    usage: ansible-vault [-h] [--version] [-v]
                         {create,decrypt,edit,view,encrypt,encrypt_string,rekey}
                         ...
    
    encryption/decryption utility for Ansible data files
    
    positional arguments:
      {create,decrypt,edit,view,encrypt,encrypt_string,rekey}
        create              Create new vault encrypted file
        decrypt             Decrypt vault encrypted file
        edit                Edit vault encrypted file
        view                View vault encrypted file
        encrypt             Encrypt YAML file
        encrypt_string      Encrypt a string
        rekey               Re-key a vault encrypted file
    
    optional arguments:
      --version             show program's version number, config file location,
                            configured module search path, module location,
                            executable location and exit
      -h, --help            show this help message and exit
      -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                            connection debugging)
    
    See 'ansible-vault <command> --help' for more information on a specific
    command.



2. 암호화되지 않은 파일을 암호화 (../vars/main.yml 파일 암호화)

  • 기존에 가지고 있는 파일을 암호화함으로 알수 없는 문자로 이루어진 파일 생성 (Plain text → Encrypt text)

  • 암호화할때 AES256 암호화 표준을 사용

  • 암호화된 파일의 key를 1234로 함

  • 실전에서는 보다 복잡하게 생성해야하지만, 해당 key의 비밀번호를 담고있는 암호화 파일을 추가로 생성하여 vault password 입력할때 활용하는 테스트를 위해 단순하게 생성

    # 암호화할 파일의 내용 확인
    $ vi ../vars/main.yml
    ---
    #사용자 목록
    root_user: "root"
    hippo_user: "hippo"
    
    #변경하고자하는 id의 비밀번호 -> 비밀번호 부분은 ####으로 표시
    root_newpasswd: "########"
    hippo_newpasswd: "########"
    
    # ../var/main.yml 파일을 암호화하여 새로운 암호화 파일 생성
    $ ansible-vault encrypt ../vars/main.yml
    New Vault password:
    Confirm New Vault password:
    Encryption successful
    
    # ../vars/main.yml 파일이 암호화되어있음을 확인 가능
    $ cat ../vars/main.yml
    $ANSIBLE_VAULT;1.1;AES256
    33363235653433386533393236363138376133666234623535313431373835323563323230653838
    3036383965373264646262316464306137623333656435370a333162616433653761336332343439
    61323933646137666663616231613539393264363032613137393538343837393838306231383861
    6265323931656562340a316539306433363436613262393633623463626361303339396430386465
    30326638623336386133303136396431336662326639623439653035373363643966633161656666
    65613632353539616365666530313532373530613239373632316532613838643434623962366332
    31333834613237633134316332343437323063386234643063303464393365326133636462356266
    63343662363237633365646535333733623966323735343865656536626664613263353332393263
    31396361303533663463313832333362353732663939616539616131653533383331343064623961
    38303966393434323266643133323635323461653265633338306430323566373236643662356565
    62326336353336613937623738323861333636336234623030376434316564386131363639643739
    38653764376634613636356665383830306230356364323932373734363831333030313730656464
    31383231653330393764323638393034646539646366336438386533323534336631336133333337
    62626434343532636338613339333739396231643934616135363836323961303032626661303737
    62313433343236636134396136633566343165343963663462336531343162383361396536313434
    35333064313739623464



3. 암호화한 ../vars/main.yml 파일이 이상없이 roles에서 적용가능한지 테스트

  • 비밀번호를 변경하는 roles

  • 암호화한 ../vars/main.yml 을 활용하기 위해서는 키가 필요

  • 키를 수동으로 입력하기 위해서는 옵션을 넣어야함(--ask-vault-pass)

  • --ask-vault-pass 옵션이 없는 경우 ansible-vault로 암호화된 파일을 읽을 수 없어서 에러 발생

    # 아래와 같이 일반 암호와 vault 암호를 같이 입력해야함 -> 정상 실행됨으로 실행 내용은 생략
    # Vault password에 들어갈 비밀번호는 "1234"
    $ ansible-playbook change_passwd_role.yml -k --ask-vault-pass
    SSH password:
    Vault password:
    
    PLAY [change passwd Role] *******************************************************************
    [...생략]



4. 암호화된 파일을 복호화 (../vars/main.yml 파일 복호화)

  • 암호화된 파일을 Plain text 파일로 복호화 (Encrypt text → Plain text)

  • 복호화할때 AES256 암호화 표준을 사용

  • 암호화된 파일에 key를 1234로 하여 복호화

    # 암호화된 ../var/main.yml 파일을 복호화하여 기존 파일으로 변경
    $ ansible-vault decrypt ../vars/main.yml
    Vault password:
    Decryption successful
    
    # 암호화된 ../vars/main.yml 파일이 복호화되어있음을 확인 가능
    $ cat ../vars/main.yml
    ---
    #사용자 목록
    root_user: "root"
    hippo_user: "hippo"
    
    #변경하고자하는 id의 비밀번호 -> 비밀번호 부분은 ####으로 표시
    root_newpasswd: "########"
    hippo_newpasswd: "########"



5. 암호화 키 제작 → 암호화할 파일의 키를 암호화

  • 암호화할 파일의 키는 "1234" → 중요한 정보를 암호화할 때 사용할 키

  • 암호화할 파일의 키를 복호화할 키는 "9876" → 암호화한 키의 내용이 복호화되면 암호화된 정보까지 도달할 수 있기에 이 부분도 복잡하게 하는 것이 중요 (테스트이기에 단순하게 적용)

  • 중요한 정보를 암호화할 키를 Plain text로 공유하면 관리에서 문제가 발생할 수 있음 → 암호화된 키로 공유하여 관리 문제 해결

    # vault password는 vault_key 파일의 키 -> 복호화할때 사용
    $ ansible-vault create ../vars/vault_key
    New Vault password:
    Confirm New Vault password:
    
    # 1234로 입력하고 wq!으로 저장하면 ../vars/vault_key 파일 생성
    1234
    
    # ../vars/vault_key 파일의 내용 확인 -> 해당 내용으로 암호화가 필요한 중요 파일을 암호화
    $ cat ../vars/vault_key
    $ANSIBLE_VAULT;1.1;AES256
    61336134633736613130643539316264356339333261623865356261366465623065613436313064
    3263356335363463623362646333366338613764643932300a303635663930653934313931303966
    37316437336635333137336330616264623264393831316537303434376138373463393361373936
    6132636239613263350a363863343233656164343832663965353433393136343465383933656636
    3962



6. 중요 파일을 암호화된 키로 암호화 → 암호화된 키 공유하여 ansible 활용

  • 암호화 키를 공유해도 해당 키의 암호키를 모르기에 문제 X

  • 중요한 파일을 암호화할 때 해당 암호화된 파일 활용 → 이전에 Plain text로 "1234" 입력하는 것과 동일 효과

  • 암호화된 키를 활용하기 위해서는 vault-password-file 옵션 사용

  • 해당 이슈 내용은 ansible 버전 업그레이드로 ansible-vault를 통해서 암호화된 파일은 ansible-vault키로 사용 X → 해결 방법으로는 6.1 부분과 6.2 부분를 보고 괜찮은 부분을 따라서 하면됨

  • ansible-vault로 encrypt한 ../vault_key 파일을 활용하여 ../main.yml 파일을 암호화할 때 문제 발생

    $ ansible-vault encrypt ../vars/main.yml --vault-password-file ../vars/vault_key
    
    # 이슈 내용: ansible-vault를 통해서 생성한 암호화 파일을 ansible-vault의 키로 사용할 경우 아래와 같은 에러가 발생함
    [WARNING]: Error in vault password file loading (default): A vault password must be specified to decrypt data
    ERROR! A vault password must be specified to decrypt data

6.1. 생성한 AES256 암호화 파일을 ansible-vault에서 볼트 암호화 파일로 인식하지 못하게 하기

  • vault_key 파일 확인
    $ cat ../vars/vault_key
    $ANSIBLE_VAULT;1.1;AES256
    61336134633736613130643539316264356339333261623865356261366465623065613436313064
    3263356335363463623362646333366338613764643932300a303635663930653934313931303966
    37316437336635333137336330616264623264393831316537303434376138373463393361373936
    6132636239613263350a363863343233656164343832663965353433393136343465383933656636
    3962
  • vault_key 파일 내용 변경 → 출력되는 내용 중에 $(달러 기호)를 삭제
    $ vi ../vars/vault_key
    ANSIBLE_VAULT;1.1;AES256
    61336134633736613130643539316264356339333261623865356261366465623065613436313064
    3263356335363463623362646333366338613764643932300a303635663930653934313931303966
    37316437336635333137336330616264623264393831316537303434376138373463393361373936
    6132636239613263350a363863343233656164343832663965353433393136343465383933656636
    3962
  • vault_key를 평문으로 인식 → ../vars/vault_key 파일을 통해 ../vars/main.yml 파일을 암호화 복호화 테스트

    # 암호화 테스트
    $ ansible-vault encrypt ../vars/main.yml --vault-password-file ../vars/vault_key
    Encryption successful
    
    # 암호화가 정상적으로 진행되었는지 확인
    $ cat ../vars/main.yml
    $ANSIBLE_VAULT;1.1;AES256
    63643230343061333339313964343937336632386364663935643736313333336238663932323865
    3730326361663139626232386562653962396263343931310a333161343061376331306530303736
    36663832626133353932383464323539656431373563613563653230623136343963306230623962
    6538353330343666380a396639323235653465356336346135646562616161306333313033336562
    65333766643234633633633532623062393033636233643534336138366465326237333932643333
    30353563343337643031353966366264383264356562316234393331393832656162653933343136
    38646331333238633766393036336431366634643863323234353133643031653033663037356236
    61393162386637326437623164323364666330613636666462366465363764663364666330303566
    36306433366539623433386434616238663063633734656131316434323332623735346335616266
    61303838393239643834343362386331386534343339313265663334323035653665616632363661
    38376433643239323564616162666535393431326533643432396466633034646562396134356437
    39626134346565326533393836653634316536633164616164393436316330323331336239336665
    64383238383930613930653065386631343933633462383966313236666532353334343137333632
    66643462626164616339303064633733303734653735313862653165633762353430313136386463
    33663434306566323161386630376130333865343238613736356332383862323765303634643732
    66383134383439356361
    
    # 복호화 테스트
    $ ansible-vault decrypt ../vars/main.yml --vault-password-file ../vars/vault_key
    Decryption successful
    
    # 복호화가 정상적으로 진행되었는지 확인
    $ cat ../vars/main.yml
    ---
    #사용자 목록
    root_user: "root"
    hippo_user: "hippo"
    
    #변경하고자하는 id의 비밀번호 -> 비밀번호 부분은 ####으로 표시
    root_newpasswd: "########"
    hippo_newpasswd: "########"

6.2. vault가 아닌 openssl을 이용하여 난수로 작성된 vault_key_by_ssl 파일 생성

  • openssl 명령어를 실행하여 vault_key_by_ssl 이라는 암호화된 파일 생성 → vault_key_by_ssl 파일로 main.yml 파일을 암호화하는 키로 활용
    # ../vars/vault_key_by_ssl 파일이름으로 암호화된 파일 생성(ansible-vault를 활용하지 않지만, openssl로 암호화한 key 활용)
    $ openssl rand -base64 2048 > ../vars/vault_key_by_ssl
  • 생성한 vault_key_by_ssl 확인
    # 암호화된 파일 내용 출력
    $ cat ../vars/vault_key_by_ssl
    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
  • 새로 생성한 vault_key_by_ssl 파일을 이용해서 ../vars/main.yml 파일을 암호화

    # 암호화 테스트
    $ ansible-vault encrypt ../vars/main.yml --vault-password-file ../vars/vault_key_by_ssl
    Encryption successful
    
    # 암호화된 ../vars/main.yml 파일 내용 확인
    $ cat ../vars/main.yml
    $ANSIBLE_VAULT;1.1;AES256
    33303566376566653234393138636562663863393431646566333262643232383862383439626531
    6433303938363137623762316234666163383238383136320a333238623731333539353065313666
    63633864663763346263663564646561666534343137616139373564363964396131343863363263
    6366663236613735320a333264323761353230306239346663656466663638323961396364323138
    35636665333737643838616161343835363732356536633833646431323465646131393432373863
    35653939326435626464373036633531303466356164656437323039343435613532653531636231
    35356237663464306566663463613939313433333031633736323165663839306266376334636336
    39356537323930656263313037396531663961396162333162613765356265653135336535316366
    39666432363036646364613165346461363830613032323961396563643466663633613635343633
    62396536656562303365346563626338353234303161306432333430303662346166353133353230
    39613636666165626362366637633061396266636561646463363966306135323835666536393765
    34316662396265336365383462643932366532663132616361396238396561663166386532636264
    64626266373266326266363739653633623664353765336136356539323665336265653461666466
    33393462633138346638313866643132346239643061353131326132336134653737646565636262
    35356131343362383532353232346430643237383165353132616133643630373466383761323030
    38333061313761373938
    
    # vault_key_by_ssl 파일을 이용해서 ../vars/main.yml 파일을 복호화
    $ ansible-vault decrypt ../vars/main.yml --vault-password-file ../vars/vault_key_by_ssl
    Decryption successful
    
    # 복호화가 정상적으로 진행되었는지 확인
    $ cat ../vars/main.yml
    ---
    #사용자 목록
    root_user: "root"
    hippo_user: "hippo"
    
    #변경하고자하는 id의 비밀번호 -> 비밀번호 부분은 ####으로 표시
    root_newpasswd: "########"
    hippo_newpasswd: "########"



7. 생성된 암호화 키 파일인 ../vars/vault_key과 ../vars/vault_key_by_ssl를 활용하여 ../vars/main.yml 파일을 암호화 → roles에서 적용가능한지 테스트

  • 암호화된 키 파일을 활용 → 6.1과 6.2 중 하나를 이용하면 됨

  • 암호화된 키 파일을 통해서 ../vars/main.yml 파일 암호화

  • roles를 이용하여 암호화된 파일이 이상 없는 지 확인 필요

  • --vault-password-file 옵션을 사용하여 암호화된 키 피일을 적용 → 암호화된 키를 통해 중요한 데이터가 암호화되어야만 정상 roles 작동

  • --vault-password-file 옵션으로 암호화된 파일을 적용하는 것은 문제 없으나, SSH 접속에는 비밀번호가 필요함으로 SSH password 부분에 적합한 비밀번호 적용 필요

  • 해당 부분도 암호화로 변경하여 자동화 할수 있지만, 해당 파일의 목적이 비밀번호 변경임으로 비밀번호 확인 차원에서 SSH 접속 비밀번호는 수동으로 남겨놓음

    # Vault password에 들어갈 비밀번호를 암호화된 파일을 이용하여 적용 -> --vault-password-file 옵션 활용
    # 정상 실행됨으로 실행 내용은 생략
    # 파일 경로는 직접 확인하여 적용 필요
    $ ansible-playbook change_passwd_role.yml -k --vault-password-file ../vars/vault_key
    SSH password:
    
    PLAY [change passwd Role] *******************************************************************
    [...생략]

※ ansible vault의 참고 사항

1. 암호화된 파일의 패스워드 변경하기

$ ansible-vault rekey ../vars/main.yml

2. 암호화된 파일의 내용 보기

$ ansible-vault view ../vars/main.yml

+ Recent posts