googleusercontent.coom / 이미지 표시 문제

사내메일서버에서 지메일로 메일발송할 경우 이미지가 표시안되는 문제가 발생했다.
해당 문제는 본문에 이미지를 삽입했을 때 발생했고 첨부파일로 넣었을 경우는 발생하지 않았다.

문제가 발생한 메일 본문

이미지가 나오지 않고 404 코드를 반환한다

<img src="https://ci3.googleusercontent.com/meips/ADKq_NaOOgOCqGIvHrYcYIpTuAvRgcg0AN7kloSXWd4lQFTMeY82IxJGj3p4mMDpxhIyNup7MGJ46SI1UVM30Ldx8JcqQ96BYIIFs4Ppn4B8DbIocydPPcshB-xDUSSmteQnsk9VhU9uHsO6R8i4euJOri1veXp3fyEf1NQ=s0-d-e1-ft#https://mail.domain.com/data/mailing/202404/29/f5abecd29fb2a516346a6cebd02591f39c98a0e8.jpg" class="CToWUd" data-bit="iit" jslog="138226; u014N:xr6bB; 53:WzAsMl0.">

구글메일은 이미지 삽입시 클라이언트에서 읽지 않고 구글 이미지 서버를 거쳐서 캐싱을 한다.

구글링으로 찾아본 해결책

https://stackoverflow.com/questions/40570117/http403-forbidden-error-when-trying-to-load-img-src-with-google-profile-pic

이미지 태그에 referrerPolicy=’no-referrer’ 속성을 추가하는 방법을 안내해준다

결론부터 말하자면 해당 태그를 넣어도 구글에서 해당태그를 아래처럼 없애버린다.

googleusercontent.com

구글 이미지 프록시에서 사내메일서버의 아이피를 블랙리스트로 등록했을
가능성을 생각해보고 우회하는 방법을 생각해봤다.

사내메일서버 아이피를 변경할 수 없는 상황이지만
여러 대역의 사용가능한 아이피가 있는 상황이기에 리버스 프록시를 사용해본다.

Reserse proxy / Nginx

구글 이미지 프록시가 메일서버에 직접 접근하는 상황을 아래처럼 변경한다

리버스 프록시 서버는 IDC내 가상서버로 구축하고
4개의 서로 다른 아이피 대역을 할당해줬다.

DNS 설정

img01-mail  IN  A x.1.x.x
img02-mail IN A x.x.2.x
img03-mail IN A 3.x.x.x
img04-mail IN A x.x.x.4

2차 도메인을 DNS서버에 설정한다. 기존 메일서버와는 다른 대역을 사용했다.

메일발송

메일 발송시 본문에서 이미지 태그를 확인하고 도메인 부분을 치환하는 코드를 작성한다.
치환시 img01 ~ img04 중 랜덤하게 사용되도록 해준다.

Nginx 설정

nginx 설정은 따로 특별한게 없다. 도메인만 여러개 추가해준다.

server {
listen 443 ssl http2;
server_name img01-mail.domain.com img02-mail.domain.com img03-mail.domain.com img04-mail.domain.com;
server_tokens off;

location / {
proxy_redirect off;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://mail.domain.com/;
proxy_redirect off;
proxy_http_version 1.1;
}

ssl_certificate /home/ssl/fullchain.pem;
ssl_certificate_key /home/ssl/_wildcard_domain.com_SHA256WITHRSA.key;
ssl_protocols TLSv1.1 TLSv1.2;
}

테스트

발송할 때마다 2차 도메인은 계속 변경되었고, 이미지도 잘 표시된다.

<img src="https://ci3.googleusercontent.com/meips/ADKq_NaOODCx4XS5A5i2FvMs7IHhVH638Rt18wraT9Lsqo6YmS0oVpeCdEerGQHHdgqODi5uY4s9BZWFfpcGS49R7JJTCOmMG4NH9HLSdVThm7g5tYzRf5go5-gacdoLbsxo3I4r-fOwswrlhRKb-4XjudQPFOC2qznJeSM=s0-d-e1-ft#https://img02-mail.domain.com/data/mailing/202404/29/1b2b7bb8190e4c444ac418b600272d3dbd713e62.jpg" class="CToWUd a6T" data-bit="iit" tabindex="0">

Proxmox VE – Resizing guest disk

Proxmox에서 생성한 VM의 디스크 용량이 부족한 상황이 발생했다.
디스크를 추가하기 보다는 사용중인 디스크의 용량을 증가시키는 방법을 선택하기로 하고 다른 VM에 테스트후 적용했다.

Proxmox WebUI

웹UI로 접속해서 해당 VM의 디스크를 선택

[Disk Action] 에서 [Resize]를 선택하고

증가시킬 용량을 입력한다

VM에 SSH로 접속

root@db-gtv:~# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 794M 1.3M 793M 1% /run
/dev/sda2 79G 73G 2.2G 98% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 794M 4.0K 794M 1% /run/user/0

디스크 용량을 확인해 보면 기존 용량으로 보인다.
파티션 조정이 필요해 보인다.

Disk /dev/sda: 120 GiB, 128849018880 bytes, 251658240 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 853010EE-DB5B-4D1D-BF27-A8485BA881EE

Device Start End Sectors Size Type
/dev/sda1 2048 4095 2048 1M BIOS boot
/dev/sda2 4096 167770111 167766016 80G Linux filesystem

디스크의 파티션을 확인한다. Proxmox WebUI에서 조정한만큼 용량이 증가한 것을 확인할 수 있다.

root@db-gtv:~# growpart /dev/sda 2
CHANGED: partition=2 start=4096 old: size=167766016 end=167770112 new: size=251654111 end=251658207

growpart 명령을 이용해서 파티션을 조정한다.

root@db-gtv:~# resize2fs /dev/sda2
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 10, new_desc_blocks = 15
The filesystem on /dev/sda2 is now 31456763 (4k) blocks long.

resize2fs 명령을 이용해서 파일시스템도 조절해준다.

root@db-gtv:~# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 794M 1.3M 793M 1% /run
/dev/sda2 118G 73G 40G 65% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 794M 4.0K 794M 1% /run/user/0

증가된 용량을 확인할 수 있다.

라즈베리파이를 무선공유기로 만들기

https://www.raspberrypi.com/software/operating-systems

라즈베리파이 이미지중 Raspberry Pi OS Lite 를 설치하고 진행한다.

필수 패키지 설치

apt install -y hostapd
apt install -y dnsmasq

설정파일

interface=wlan1
driver=nl80211
ssid=jongwan
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=12345678
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

/etc/hostapd/hostapd.conf

interface=wlan1
dhcp-range=192.168.10.2,192.168.10.20,255.255.255.0,24h
domain=wlan
address=/gw.wlan/192.168.10.1

/etc/dnsmasq.conf

# 아래 내용 추가
interface wlan1
static ip_address=192.168.10.1/24
nohook wpa_supplicant

/etc/dhcpcd.conf

# 아래 주석 해제
#net.ipv4.ip_forward=1

/etc/sysctl.conf

root@raspberrypi:/# sysctl -p
net.ipv4.ip_forward = 1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

서비스 실행

systemctl unmask hostapd
systemctl enable hostapd
systemctl start hostapd
systemctl enable dnsmasq
systemctl start dnsmasq

제주도 한라산 (성판악~백록담~관음사코스)

5월 첫째주 한라산에 다녀왔다.

날씨 예보로는 아슬아슬했는데
안타깝게도 정상에 올라서부터 비가 내리기 시작했고
하루종일 비가 내린날이었다.

한라산은 날씨에 행운이 따라야 한다나??

전날 저녁비행기를 타고 제주도로 이동해서
제주버스터미널 근처 게스트하우스에서 묵었다.

제주버스터미널에 숙소를 잡은 이유는
여기서 161번 급행 첫차가 06:10에 출발하기 때문이다.

당일 아침 첫 비행기를 타서 제주도로 오는 경우
공항 3번 출구 앞 버스정류장에서 07:20분에 161번 버스를 탈 수 있다.

이게 가능하려면 김포공항에서
06:00~06:10 비행기를 연착없이 타야 하는데
빠듯하게 가느니 전날가서 한숨자는게 나아보인다

아침일찍 일어나서 터미널에 나와보면
바로옆에 CU편의점이 크게 있으니 여기서 물과 간식거리를 구매한다.

161번 버스는 터미널 안쪽이 아니라 밖에서 탄다.

성판악에 07:30 정도에 도착했다.
주차장은 한산한 편이었다.
아마도 비가 예보되어 있어서 그랬지 싶다.

이날 성판악은 시간별로 모두 예약이 완료되었었다.
https://visithalla.jeju.go.kr/main/main.do

진달래밭대피소까지 오르면서 어려웠던 구간은 없었다.

입산제한시간 확인!!

중간에 몇미터를 올라왔는지 저런식으로 세워져 있다.

정상에 다오니 구름속..

기온이 낮은편은 아니었던것 같은데,
바람이 불고 비를 맞아서 체온이 떨어져 버렸다.

이날 수학여행 온 고등학생들이 성판악에 오르다가
저체온증으로 구조대가 출동했다고 한다.
비소식이 있으면 보온에 신경을 쓰도록 하자.

춥고 바람불고 구름속이어서 백록담은 보이지도 않고
사진만 찍고 관음사 방면으로 하산을 시작한다

관음사 탐방로입구 버스정류장에는
475번 버스가 다니고 배차간격이 길어서 내려오는 시간을 잘 맞춰야 한다.

오후 배차시간
11:58, 13:28, 14:48, 15:43, 16:38, 17:28, 18:23, 19:13, 19:58

제주대학교에서 공항가는 버스로 환승이 가능하나
제주도에 온김에 동문시장에서 국수먹고 공항으로 갔다.

오늘 운동기록!!
성판악에서 올라가는건 힘들지 않고
관음사방면으로 내려가는 길이 길어서 조금 힘든정도??
그리고 관음사로 올라가면 난이도가 확~ 올라갈 듯하니 다음엔 관음사로 올라가기로..

최고높이는 GPS 오차 때문에….

HAProxy + Apache2 웹서비스 이중화 구성하기

HAProxy 설치

우분투 22.04 기준 패키지 매니저로 설치한다.

apt install haproxy

haproxy.cfg

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        ssl-default-bind-options no-sslv3
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
        ssl-default-server-options no-sslv3
        ssl-default-server-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

####################################################
# stats
####################################################
listen stats
        bind *:8080
        stats enable
        stats uri /
        stats realm HAProxy\ Statistics
        stats auth admin:1234
        stats refresh 5s

####################################################
# jongwan.com
####################################################
frontend jongwan_com-front
        mode http
        bind 172.16.0.10:80
        redirect scheme https code 301 if !{ ssl_fc }

frontend jongwan_com-ssl-front
        mode http
        bind 172.16.0.10:443 ssl crt /etc/haproxy/ssl/_wildcard_jongwan_com.pem
        default_backend jongwan_com-backend

backend jongwan_com-backend
        mode http
        option httpchk
        option forwardfor
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request set-header X-Forwarded-Proto https if { ssl_fc }
        http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
        server www1 10.0.0.1:80 check weight 1
        server www2 10.0.0.2:80 check weight 1 backup
listen stats
        bind *:8080
        stats enable
        stats uri /
        stats realm HAProxy\ Statistics
        stats auth admin:1234
        stats refresh 5s

stat은 8080포트로 바인딩하고 암호를 설정해준다.

frontend jongwan_com-front
        mode http
        bind 172.16.0.10:80
        redirect scheme https code 301 if !{ ssl_fc }

프런트앤드를 추가한다.

  • bind : 외부에서 접근하는 아이피 (공인아이피)
  • redirect : https 포트로 리다이렉트한다.
frontend jongwan_com-ssl-front
        mode http
        bind 172.16.0.10:443 ssl crt /etc/haproxy/ssl/_wildcard_jongwan_com.pem
        default_backend jongwan_com-backend

HTTPS 프런트앤드를 설정한다.

  • bind : 외부에서 접근하는 아이피를 입력한다. PEM 형식의 인증서를 추가해야 하고 아래쪽에 만드는 방법이 있다.
  • default_backend : 기본 백앤드
backend jongwan_com-backend
        mode http
        option httpchk
        option forwardfor
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request set-header X-Forwarded-Proto https if { ssl_fc }
        http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
        server www1 10.0.0.1:80 check weight 1
        server www2 10.0.0.2:80 check weight 1 backup
  • mode : http 방식으로 health 체크를 한다. ssl 확인을 위해 header를 사용하기 때문에 tcp로 하면 동작하지 않는다.
  • server : 실제 웹서버 정보를 입력한다. 사용자와 통신은 443 (SSL) 통신을 하지만 haproxy와 webserver간에는 80으로 통신한다.

아파치 웹서버 설정

<VirtualHost *:80>
        ServerAdmin aiseki@gmail.com
        DocumentRoot /home/jongwan/public_html
        ServerName jongwan.com
        ServerAlias www.jongwan.com

        <Directory /home/jongwan/public_html/>
                Options FollowSymLinks
                AllowOverride FileInfo
                Require all granted
        </Directory>

        RemoteIPHeader X-Forwarded-For
        RemoteIPInternalProxy 172.16.0.10/24

        #LogLevel info ssl:warn
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
  • RemoteIPHeader X-Forwarded-For : 사용자는 haproxy를 통해서 웹서버에 접근하기 때문에 실제 웹서버 로그에는 haproxy 아이피가 나온다. 이때 haproxy는 X-Forwarded-For 헤더에 클라이언트의 실제아이피를 담아준다.
    mod_remoteip 모듈을 활성화하고 해당 옵션을 이용하면 아파치가 실제 클라이언트 아이피를 가져올 수 있다.
    PHP의 경우 REMOTE_ADDR 값에 영향을 준다.
  • RemoteIPInternalProxy : haproxy 아이피 대역을 입력한다.

mod_remoteip 활성화하기

a2enmod remoteip

PEM 인증서 생성하기

key, crt 파일을 이용해서 pem 형식의 인증서를 만드는 방법이다.
합친파일에서 ^M 문자열이 있을 경우 오류가 나기 때문에 tr 명령을 이용해서 삭제해준다.

cat _wildcard_jongwan_com_SHA256WITHRSA.key _wildcard_jongwan_com.crt ChainCA/rsa-dv.chain-bundle.pem | tr -d '\015' > _wildcard_jongwan_com.pem

금학산 (금학공원~매바위~정상~마애불상~원점회귀)

철원여자고등학교로 올라오면 지도에 표시한 위치에 주차장이 있습니다.
큰 주차장에 무료로 사용이 가능하고,
에어건도 있어서 편리합니다.

금학산은 전체적으로 힘들지는 않았고,
쉬엄쉬엄 올라가면 금방 정상에 도착합니다.
정상에서 마애불상쪽은 하산시 이정표를 잘 보면서 내려가야 하는데
네이버나 다음지도의 등산로와 살짝 안맞는듯 합니다.

내려오다가 계곡에서 뱀 봤습니다!!!

여기로 쭉 올라가면 금학체육공원이 나옵니다.

이곳으로 올라가서 시계 반대방향으로 등산할 예정입니다.
금학체육공원 ~ 매바위 ~ 정상 ~ 마애불상 ~ 거북이약수터 ~ 금학체육공원 ~ 주차장

매바위!!!

가끔 나오는 가파른 계단

정승바위!!!

정상옆 헬기장입니다.

947미터 금학산 정상입니다.

고대산이 보이네요.
여기서 고대산 연계산행이 가능하니 여유가 된다면 가보는 것도 좋겠습니다.

네이버나 다음지도의 등산로를 보고 내려오면
길이 약간 어긋납니다.
거북이 약수터로 내려와서 C코스로 이동한 뒤 주차장으로 갑니다.

C코스가 은근 오르막길

삼악산 등선입구~정상~상원사~의암매표소 코스

2월이 끝나갈 무렵 삼악산에 올랐다.

오전일찍 청량리에서 청춘ITX를 이용해서 강촌역까지 이동한다. 등선폭포로 가려면 쉬엄쉬엄 걸어가도 되고, 버스를 타면 금방이다.
1번출구에서 5번 또는 7번 버스를 타면 등선입구에서 내릴 수 있다.

등선입구에서 내리면 횡단보도가 없고 지하도가 있으니 입구가 보이는 곳까지 걸어가보자. 처음에 무단횡단을 해야하나 고민을 많이 했다.

지하도 입구
등선폭포 정보
입장료

입장료가 있는데 [춘천사랑상품권]으로 돌려준다. 산에서 내려와서 춘천시내에서 밥을 먹기로 했는데 그 때 사용이 가능했다.

계곡이라 아직 얼음이 있다
수많은 돌탑들
레고랜드가 보인다

암벽구간인데 기어서 올라가는 사람이 보일 정도로 가파르다. 거기다가 미끄럽기도 해서 많이 위험했다.

삼악산을 오른다면 의암매표소(상원사) ~ 정상 ~ 등선입구로 가는게 비교적 안전할 것 같다.

심지어 사진에는 없는데 상원사 위쪽 구간이 모두 얼음이라 아이젠 없이 가다 넘어지는 사람을 몇명 봤다.

춘천에 왔으니깐 닭갈비는 필수코스

기차시간이 남아서 택시타고 온 구봉산 카페거리

1월 마지막주 월악산 등산 (덕주사~영봉~보덕암)

1월 마지막주 월악산에 올랐다.
오전 8시쯤 덕주사에서 출발~송계삼거리~영봉~중봉~하봉~보덕암~수산리 코스이다.

덕주사에 주차하고 버스를 이용해 수산리로 이동한 뒤 보덕암부터 올라가는 코스가 있는데, 하봉~중봉~영봉코스가 가파르다고 해서 덕주사부터 올라가기로 했다.

결론부터 말하자면 월악산은 덕주사~영봉~보덕암 코스가 조금 더 수월한 코스같다.

덕주사에 있는 주차장이다. 20여대는 주차할 수 있을 듯?

차량으로 이동했기에 주차를 해야 했다.
덕주휴게소에 주차장이 크게 있으니 거기에 주차를 해도 된다. 덕주휴게소에 주차를 하고 바로 앞에서 버스를 타고 수산리로 이동하는 방법이 있다.

우리는 덕주사에 주차를 하고 수산리에서 버스나 택시를 이용해서 돌아오기로 했다.

덕주사 입구에 있다. 여기부터 4.9km 이다.

전날에 눈이 좀 내렸다고 한다.
출발할때는 날이 맑아서 괜찮을 줄 알았는데 중간에 눈보라가 치다 맑아졌다를 반복했다.

계단이 잘 되어 있어서 오르는데 크게 불편하지 않았다.

잘되어 있는 계단이긴 하지만 쉽지는 않다. 절벽을 끼고 오르는 가파른 계단이 많다.

오른쪽이 영봉이고 왼쪽이 중봉이다.
영봉으로 바로 오르지는 못하고 오른편으로 돌아서 올라간다.

영봉아래 낙석주의구간이다.

영봉까지는 계단으로 계속 올라가야 하는데 많이 가파르다. 가파른것도 있는데 바닥 아래가 절벽이라서 아찔한 구간이다.

중봉과 충주호가 한눈에 보인다.

보덕암

여기는 보덕암 입구이다. 여기서 오르는 방법도 있다.

보덕암에서 수산리까지는 30여분 걸어야 한다. 수산교까지 가면 버스를 탈 수 있으나 배차시간이 길어서 잘 확인해봐야 한다.

수산교쯤에서 보덕암으로 가는 콜택시에 양해를 구하고 합승을 해서 겨우 덕주사로 돌아왔다.

콜택시를 알아봤는데 일단 택시를 타기가 힘들다. 콜택시 전단지, 인터넷을 보고 전화를 해봐도 비싼건 그렇다치고 오지를 않는다.
근처 콜택시를 부르는 것보다 수안보쪽 콜택시를 부르는게 더 빠르다고 한다.
30분전에 미리 콜을 해두고 시간을 잡아두자.

집에 가는 길에 들른 원조중앙탑막국수인데, 보쌈이 괜찮았고 다른건 그럭저럭 먹을 만 했다.

외부스크립트를 이용해서 HAProxy node 체크하기

HAProxy + MariaDB Galera Cluster 구성을 하고 테스트를 진행하니 문제가 발생해서 글을 남겨본다.

HAProxy

haproxy.cfg 설정파일에서 아래 옵션을 사용

option mysql-check user haproxy

이 옵션은 TCP 포트로의 접속가능 여부만 판단해서 health check를 한다.
Galera Cluster의 경우 노드가 복구될 때 쿼리를 하면 아래 메시지가 출력된다.

WSREP has not yet prepared node for application use

따라서 이 경우는 HAProxy에서 노드를 살려줘서는 안된다.

MariaDB Galera Cluster

MariaDB [(none)] > show global status where variable_name='wsrep_local_state';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| wsrep_local_state | 4     |
+-------------------+-------+

동기화가 완료되서 사용이 가능한 상태값이다.
다른 상태값은 아래 링크에서 확인한다.
https://mariadb.com/docs/ent/ref/mdb/status-variables/wsrep_local_state/

HAProxy external-check

기존에 mysql-check를 외부 스크립트를 이용하도록 변경한다.
외부 스크립트는 wsrep_local_state 값을 읽어서 원하는 값이면 exit 0 을 리턴하고 다른값이면 exit 255를 리턴시켜주면 된다.

/etc/haproxy/haproxy.cfg

global
        log /dev/log    local0
        log /dev/log    local1 notice	
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        external-check
        insecure-setuid-wanted

frontend mysql-front
        bind *:3306
        mode tcp
        default_backend mysql-back

backend mysql-back
        mode tcp        
	#option mysql-check user haproxy
	option external-check
        external-check path "/usr/bin:/bin"
        external-check command /etc/haproxy/script/check_node.sh
	balance roundrobin
        server db1 172.16.0.20:3306 check
        server db2 172.16.0.21:3306 check backup weight 2
        server db3 172.16.0.22:3306 check backup weight 1
  1. global 항목에 external-check 값이 추가되었다.
  2. external-check를 사용하기위해서 insecure-setuid-wanted 값을 추가해야한다
    https://www.haproxy.com/blog/announcing-haproxy-2-2/#security-hardening
  3. backend 항목에 기존 mysql-check 항목을 external-check로 변경
  4. external-check path 추가
  5. external-check command 추가

/etc/haproxy/script/check_node.sh

#!/bin/bash

MYSQL_HOST="$3"
MYSQL_PORT="$4"
MYSQL_USERNAME="haproxy"
MYSQL_PASSWORD=""
MYSQL_BIN="/bin/mysql"
MYSQL_OPTS="--no-defaults --connect-timeout=10 -snNE"
CMDLINE="$MYSQL_BIN $MYSQL_OPTS --host=$MYSQL_HOST --port=$MYSQL_PORT --user=$MYSQL_USERNAME -e"
WSREP_LOCAL_STATE_CHK=`$CMDLINE "SHOW GLOBAL STATUS WHERE VARIABLE_NAME='wsrep_local_state'" | tail -1`

if [ "$WSREP_LOCAL_STATE_CHK" != "4" ]; then
    exit 255
fi

exit 0

파라메터 정보

$1 = Virtual Service IP (VIP)
$2 = Virtual Service Port (VPT)
$3 = Real Server IP (RIP)
$4 = Real Server Port (RPT) 
$5 = Check Source IP 

$3, $4를 이용해서 노드의 상태를 읽는다.