https://www.youtube.com/watch?v=gy22liV3oNk 

 

ヨホホホ ヨホホホ

요호호호 요호호호

ビンクスの 酒を 届けにゆくよ

빙크스노 사케오 토도케니유쿠요

[ 빙크스의 술을 전하러 간다네 ]


海風 気まかせ 波まかせ

우미카제 키마카세 나미마카세

[ 해풍에 실려 파도에 실려 ]

潮の向こうで 夕日も騒ぐ

시오노무코우데  유우히모사와구

[ 수평선 멀리 석양도 넘실대네 ]


空にゃ 輪をかく鳥の唄

소라냐 와우카쿠 토리노 우타

[ 하늘엔 빙글빙글 노니는 새의 노래 ]

さよなら港つむぎの里よ

사요나라 미나토 츠무기노 사토요

[ 안녕 항구여, 정들었던 고향이여 ]

 

ドンと一丁唄お船出の唄

돈토잇쵸 우타오 후나데노우타

[ 우렁차게 한바탕 부르자, 출항의 노래 ]

 

金波銀波も しぶきにかえて

킨파긴은파모 시부키니카에테

[ 금물결 은물결도 물보라로 바꾸며 ]

 

おれ達ゃゆくぞ 海の限り

우레타챠 유쿠조 우미노 카기리

[ 우리는 간다네, 저 바다 끝으로 ]

ビンクスの酒を届けにゆくよ

빙크스노 사케오 토도케니유쿠요

[ 빙크스의 술을 전하러 간다네 ]


我ら海賊 海割ってく

와레라 가이조쿠 우미왓테쿠

[ 우리는 해적, 바다를 가르며 간다 ]


波を枕に 寝ぐらは船よ

나미오 마쿠라니 네구라와 후네요

[ 파도를 베개 삼아, 잠자리는 배라오 ]


帆に旗に 蹴立てるはドクロ

호니하타니 케타테루와 도쿠로
[ 돛에 깃발에 휘날리는 그것은 해골 ]

嵐がきたぞ 千里の空に

아라시가 키타조 센리노 소라니

[ 폭풍우가 왔구나, 천리의 하늘에 ]

 

波がおどるよ ドラムならせ

나미가 오도루요 도라무 나라세

[ 파도가 춤춘다 드럼을 울려라 ]

おくびょう風に 吹かれりゃ最後

오쿠뵤우카제니 후카레랴 사이고

[ 두려움의 바람에 휘둘리면 그때는 끝 ]


明日の朝日が ないじゃなし

아스노 아사히가 나이쟈나시
[ 내일 아침해가 없는 것도 아닌걸 ]

ヨホホホ ヨホホホ
요호호호 요호호호

ビンクスの酒を届けにゆくよ

빙크스노 사케오 토도케니유쿠요

[ 빙크스의 술을 전하러 간다네 ]

 

今日か明日かと宵の夢

쿄우가 아스카토 요이노 유메

[ 오늘일까 내일일까, 애타는 초저녁 꿈 ]


手をふる影に もう会えないよ

데오후루 카게니 모우아에나이요

[ 손 흔드는 그림자, 다시는 만나지 못하리 ]


何をくよくよ 明日も月夜

나니오쿠요쿠요 아스모 츠쿠요

[ 끙끙대서 무엇하랴, 내일도 달밤이라오 ]


ビンクスの酒を届けにゆくよ

빙크스노 사케오 토도케니유쿠요
[ 빙크스의 술을 전하러 간다네 ]

 

ドンと一丁唄お 海の唄

돈토잇쵸 우타오 우나바노우타

[ 우렁차게 한바탕 부르자, 바다의 노래 ]


どうせ誰でも いつかはホネよ

도우세다렛데모 이츠카와 호네요

[ 어차피 누구나 언젠가는 백골이라오 ]

 

果てなし あてなし 笑い話

하테나시 아테나시 와리아바나시

[ 끝없이 한없이 즐거운 이야기 ]

ヨホホホ ヨホホホ

요호호호 요호호호


반응형

회사에서 라이센스를 유지하려면 감사를 받아야하고 그 항목중에는 퇴사자 처리 규칙이 존재한다.

계정관리가 완전히 되면 상관이 없겠지만 혼자서 한국/외국 사무실과 인프라 관련 계정을 관리하다보니

직접 관리하기가 생각보다 어렵다. 각국의 인사팀에서 slack은 확실하게 관리해주고 있어서 slack 기준으로 퇴사자를 비교한다.

대부분 API를 제공해줘서 (github, aws, private cloud, apm monitoring tool) 문서를 보고 알아서 만들어다가 썼는데

 

Jenkins는 예외였다..

관리하려면 jenkins 사용자 목록을 가져와야 하고 그것과 관련한 API가 있긴한데

Script Console에서 Groovy script 문법을 이용해서 가져오는 방법이 있다.

다른 방법은 못 찾았다. 분명 더 편한 방법이 있을텐데...

 

개발, 스테이지 등.. 환경별로 다르게 jenkins를 사용하고 있고 여기에 각각의 계정이 존재한다.

(그룹계정을 사용하면 편한데 auditor 지적사항에 걸리면 안되서 사용 불가하다.)

 

외국 현지 부서의 인력이 드나드는 것은 공유가 안되서 알기가 어렵다. 거기에도 담당인력을 뽑아주면 되긴하지만.. 일단 혼자 하게 되었다.

 

 

Groovy script를 이용하는 방법이 있다.

stackoverflow.com/a/56558259

 

'Manage Jenkins' 를 클릭하고 좀 내려보면 'Script Console'이 있는데 그것을 이용한다.

 

 

curl을 이용해서 jenkins에 로그인 해서 Groovy script를 돌릴 수 있다.

참고로 명령어에 id와 key 정보가 있으니 내부망에서 안전하게 수행하는것을 권고한다. 

 

1. API token이 필요하다. 이 것은 내 계정의 Configure에서 만들 수 있고 적절하게 이름을 붙여준다.

curl 명령어

curl --user '계정:API_TOKEN' -XPOST https://jenkins.enqdeq.net/scriptText -d 'script=Hudson.instance.getSecurityRealm().getAllUsers().each%20{%20println%20it%20}'

사용한 옵션

  • --user의 ID:API_TOKEN 정보로 auth 획득
  • -XPOST를 이용해서 groovy script를 run 한다. (참고로 위의 url은 존재하지 않고 본인의 jenkins url을 사용한다)
  • -d 로 전달하려는 데이터 추가 (groovy script를 한줄로 적는데 space를 사용하면 "Illegal character SPACE=' '" 에러가 발생하기 때문에 url 인코딩 시킨 %20으로 대신한다.

명령어 결과는 실제로 jenkins에서 수행한것과 동일하게 보인다.

 

그 결과와 퇴사자 계정 비교해서 처리하도록 해두면 완료

간단하게 적어두긴했으나 웹에서 수동으로 Groovy script 돌리던것을 curl 명령어로 할 생각을 하기까지 1년정도 걸렸다.

 

 

 

반응형

안녕하세요 쿤드입니다. 🍀

 

가끔씩 보고 싶은 정보들을 모아 블로그에서 보고 싶을때 정보를 쫙 모아다가

Tistory의 OpenAPI를 이용해서 올리곤 했었습니다. (가끔이라서 수동으로 함)

 

오늘 오랜만에 좀 보려고 했는데

자꾸 400 Error가 발생하고 이유는 모르겠고.. 뒤져보니 response_type=code 방식을 이용해서 

하라고 하는 것을 보니 뭔가 변경된것 같았습니다.

 

Open API 사용하기 위한 App 등록이 선행되어야 하는데
이는 검색하면 많이 나와서 넘어갑니다.

 

자세히 Autoriztion Code 방식을 읽어보니 기존에 제가 인증받아서 사용하던 code에서 끝나는 것이 아니라

그 code를 가지고 token을 받아서 그 token을 이용해야 하는 것이 었습니다.

 

그래서 방법은 총 3단계 (기존엔 2단계)

  1. Tistory Login
  2. Authentication code 발급
  3. Access Token 발급

 

확인하는 방법은 2가지가 있습니다.

웹브라우저에서 해보거나, 뭐가 되었든 코드로 짜서 자동으로 하거나

우선은 수동으로 먼저 확인해봅니다. python3 코드는 이 페이지 하단에서 볼 수 있습니다.

 

웹브라우저에서 직접 해본다.

1번 과정 - https://www.tistory.com 로그인한다.

2번 과정 - Autentication Code 발급 받는다.

웹 브라우저에 입력할 내용

https://www.tistory.com/oauth/authorize?client_id=app의 ClientID&redirect_uri=리다이렉션 받을 URI&response_type=code  

 

예시(아래 것은 샘플이라 에러페이지 나옴, client_id에 임의의 값을 넣어서 되지 않음, redirection은 내 맘대로함)

https://www.tistory.com/oauth/authorize?client_id=d962867605b93asdfasdfasd6fb96f8cc27568b141c&redirect_uri=sfixer.tistory.com&response_type=code

 

 

 

3. Access Token을 발급 받는다.

웹 브라우저에 입력할 내용

www.tistory.com/oauth/access_token?client_id=나의 CLIENT_IDc&client_secret=나의 CLIENT_SECRET&redirect_uri=설정한 redirect uri &code=2번과정에서 받아온 code 정보&grant_type=authorization_code

 

예시 (샘플이라 아무정보나 들어있음, 본인것에 맞게 바꿔야함)

www.tistory.com/oauth/access_token?client_id=ddszxcvzxcv36fb96f8cc27568b141c&client_secret=d962867zxcvzxcvelkasjdflkjasldk51ca867454aac07d9b98bde63553ba3d8a93&redirect_uri=sfixer.tistory.com&code=a1175b123409821093saldjfklasdjflkasdjflke91c5a3dc8b4514268a4e3a066&grant_type=authorization_code

 

 

코드로 구현한다

 

위에 처럼 해도되지만 간단하게 파이썬 코드 몇줄로 3단계 동작을 수행하겠습니다. 

개인정보들은 환경변수에 등록해서 가져와서 썼기때문에 그 부분만 따로 (하드코딩이든 뭐든) 처리해주시면 동작합니다.

테스트까지는 해보았습니다.

물론 아래의 제가 한 코드보다 훨씬 더 간결하게 구현이 가능할 것입니다. 

이를 공유한 이유는 저 처럼 삽질하는 사람을 좀 돕고자 공유했습니다.

 

Python3.8.5을 사용했으며

사용했던 패키지 버전 정보입니다.

  • requests==2.24.0
  • selenium==3.141.0
#!/usr/bin/env python3
import os
import re
from requests import get
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


# tistory에 로그인을 합니다.
def tistory_login():
    tistory_id = os.environ.get('TISTORY_ID')
    tistory_pw = os.environ.get('TISTORY_PW')
    chromedriver_path = os.environ.get('CHROMEDRIVER_PATH')
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # chrome 띄워서 보려면 주석처리
    driver = webdriver.Chrome(chromedriver_path, options=chrome_options)
    driver.implicitly_wait(3)
    driver.get('https://www.tistory.com/auth/login?redirectUrl=http%3A%2F%2Fwww.tistory.com%2F')
    driver.find_element_by_name('loginId').send_keys(tistory_id)
    driver.find_element_by_name('password').send_keys(tistory_pw)
    driver.find_element_by_xpath('//*[@id="authForm"]/fieldset/button').click()
    return driver


# authentication code 정보를 가져옵니다.
def get_authentication_code(driver, client_id, redirect_url):
    req_url = 'https://www.tistory.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&state=langoo' % (client_id, redirect_url)
    driver.get(req_url)
    driver.find_element_by_xpath('//*[@id="contents"]/div[4]/button[1]').click()
    redirect_url = driver.current_url
    temp = re.split('code=', redirect_url)
    code = re.split('&state=', temp[1])[0]
    return code


# http://www.tistory.com/guide/api/index
# access token 정보를 가져옵니다.
def get_access_token(code, client_id, client_secret, redirect_url):
    url = 'https://www.tistory.com/oauth/access_token?'
    payload = {'client_id': client_id,
               'client_secret': client_secret,
               'redirect_uri': redirect_url,
               'code': code,
               'grant_type': 'authorization_code'}
    res = get(url, params=payload)
    token = res.text.split('=')[1]
    return token


def main():
    client_id = os.environ.get('TISTORY_CLIENT_ID')
    client_secret = os.environ.get('TISTORY_CLIENT_SECRET')
    redirect_url = os.environ.get('TISTORY_REDIRECT')
    driver = tistory_login()
    code = get_authentication_code(driver, client_id, redirect_url)
    token = get_access_token(code, client_id, client_secret, redirect_url)
    print(token)


if __name__ == '__main__':
    main()
반응형

'기타' 카테고리의 다른 글

빙크스의 술 (ビンクスの酒) 번역, 가사  (7) 2023.03.12
Jenkins 사용자 목록 curl로 가져오기  (851) 2020.12.29
테넌트  (656) 2020.07.23
TCP Status 상태에 대해서  (433) 2020.07.15
TCP 통계수치 변화 (장애 상황)  (1029) 2020.07.15

안녕하세요 쿤드입니다. 🍀

테넌트의 개념에 대해서 알아보려고 합니다.

 

테넌트(tenant): 클라우드 인프라/서비스 제공 방식

  • 싱글 테넌트: 1개 서버에 대해 1개 기업의 데이터, 어플리케이션만 제공
  • 멀티 테넌트: 다른 사용자들과 서버, 스토리지를 공유

싱글과 멀티의 차이는 하드웨어를 공유하는가 안 하는가의 차이입니다.

 

이해를 돕기위해 이미지를 같이 보면

독립적으로 구성이 될 수록 Single-Tenant에 가깝고

Multi-Tenant에 가까워 질수록 사용자가 모든 자원을 공유해서 사용합니다.

출처: http://publicstaticmain.blogspot.com/2016/05/multitenancy-with-spring-boot.html

 

멀티테넌시의 장점으로는 비용 절감 입니다. (출처: http://www.itworld.co.kr/news/101255)

그리고 관리상의 이점도 있습니다.

하드웨어 리소스를 효율적으로 사용할 수 있고, 

하드웨어에 설치된 software에 보안 patch를 하거나 upgrade 하는 경우에도 1곳만 신경써주면 되기때문입니다.


반대로 단점으로는

내부적으로는 각 사용자별로 isolate 시켜야하고, 한곳의 보안이 뚫리게 되면 모든 사용자들의 정보가 다 유출되기때문에 

이를 관리하기 위한 인력의 비용도 무시할 수는 없습니다.

반응형

안녕하세요 쿤드입니다. 🍀

RFC 793에 나와있는 상태도를 바탕으로 하나씩 따라가면서 확인하면 보입니다.

python2로 구현된 간단한 tcp client/server 코드와 함께 확인해보겠습니다.

 

* TCB: Transmission Control Block


 

ESTABLISHED까지는 1가지 경우인데
종료할때는 2가지 case로 나뉩니다. RFC793 Link

  • Normal Close(일반 종료): FIN-WAIT-1 ➡️ FIN-WAIT-2 ➡️ TIME-WAIT
  • Simultaneous close(동시 종료): FIN-WAIT-1 ➡️ CLOSING ➡️ TIME-WAIT
일반 종료 
- 어느 한쪽에서 종료하기 위해 FIN을 날린 경우
동시 종료
- Clinet, Server 양쪽에서 동시에 FIN을 날린 경우

Python Code로 테스트 (Code link)

Server Client

 

Server쪽에서 일반 종료인 경우 netstat으로 확인해서 보았습니다.

 

Server에서 socket() 열고, bind()하고 listen() 함수 호출해서 Listening을 하면

  tcp        0      0 0.0.0.0:9999            0.0.0.0:*               LISTEN      8268/python          off (0.00/0/0)

 

Client에서

connect() 호출하면
  tcp        0      0 SERVER_IP:9999      CLIENT_IP:36391     ESTABLISHED 8268/python          off (0.00/0/0)

 

send(), recv() 호출 이후 종료
  tcp        0      1 SERVER_IP:9999      CLIENT_IP:36391     FIN_WAIT1   -                    on (0.17/0/0)
  tcp        0      0 SERVER_IP:9999      CLIENT_IP:36391     FIN_WAIT2   -                    timewait (8.99/0/0)
  tcp        0      0 SERVER_IP:9999      CLIENT_IP:36391     FIN_WAIT2   -                    timewait (7.97/0/0)
  tcp        0      0 SERVER_IP:9999      CLIENT_IP:36391     TIME_WAIT   -                    timewait (59.90/0/0)
  tcp        0      0 SERVER_IP:9999      CLIENT_IP:36391     TIME_WAIT   -                    timewait (58.88/0/0)
  tcp        0      0 SERVER_IP:9999      CLIENT_IP:36391     TIME_WAIT   -                    timewait (57.86/0/0)


CLOSE_WAIT 상태는 상태도만 봤을때 이해가 잘 안가서 Server/Receiver 쪽에서 억지로 재현해보았습니다.

  • Client/Sender에서 ESTABLISHED 이후에 data를 보냄
  • Server/Receiver에서 'ACK!' 라고 응답 (60sec 대기)
  • Client/Sender에서 data를 보냄
  • Server/Receiver는 여저히 sleep으로 대기상태
# 서버쪽 응답하는 thread 코드
def handle_client_connection(client_socket):
    while True:
        request = client_socket.recv(1024)
        print 'Received {}'.format(request)
        print 'send ack & sleep'
        try:
            client_socket.send('ACK!')
            time.sleep(60)  # <--- 여기서 막음 
        except socket.error as error:
            break
    client_socket.close()
  • 이때 Client/Sender는 응답을 못 받아서 대기중인 상태인데 강제로 종료 (Ctrl + C, KeyboardInterrupt)

 

이렇게 하는 경우 또 다른 client에서 붙고 마찬가지로 멈춰버린 상태에서 client process 강제 종료


tcp        0      0 0.0.0.0:9999            0.0.0.0:*               LISTEN      17043/python         off (0.00/0/0)
tcp       54      0 SERVER_IP:9999      CLIENT1_IP:39099     CLOSE_WAIT  17043/python         off (0.00/0/0)
tcp       54      0 SERVER_IP:9999      CLIENT2_IP:47657      CLOSE_WAIT  17043/python         off (0.00/0/0)

 

이 예시에서는 sleep 60으로 60s 지나면 해소가 되는데

Deadlock이라도 걸려서 저 상태가 계속해서 지속되면 결국엔 CLOSE_WAIT이 쌓여서 사용 가능한 PORT를 전부 사용하게 될테고

서버가 행업이 됩니다.

저 상태에서 Server side가 close를 호출하지 못하면 CLOSE_WAIT은 자동으로 사라지지도 않습니다.

 

이것이 실제 production 환경에서 발생한다면

dead lock 걸린 부분을 찾아서 소스 코드를 수정하기 전까지는 

시스템 엔지니어는 주기적으로 CLOSE_WAIT 개수를 체크해서 서버 프로세스를 재시작해주면서 버티는 방법밖에는 없어보입니다.

반응형

'기타' 카테고리의 다른 글

Python3를 이용한 Tistory Authentication Code 방식 인증 (2020.09.01 변경사항 반영)  (2022) 2020.09.25
테넌트  (656) 2020.07.23
TCP 통계수치 변화 (장애 상황)  (1029) 2020.07.15
TCP 통계  (145) 2020.07.14
Kerberos Setup (KR)  (964) 2019.08.22

안녕하세요 쿤드입니다. 🍀


엔지니어로 밥먹어 먹고 살고 있는데

TCP를 제대로 아는것이 없어서 하나씩 이해해보려고 하는중에 있습니다.

실제로 사용하는것의 값은 없애고 factor중에서 변화폭이 컸던 것들 위주로 간추려서 정리를 해보겠습니다.

 

물론 네트웍 트래픽만 봐도 장애라는것을 인지할 수는 있습니다.

평소 장애

 

TCP 통계 지표를 24개만 모아서 보고 있는데 (1분마다 이전과 현재의 증가한 차이 값을 수집해서 추이를 봄)

그중에 10개만 추려보았고 

그 중에서 다시 추려보니 ActiveOpens, PassiveOpens 추이만 봐도 장애 예측은 가능하겠네요..

 

당시 앞단에 있던 nginx에서 발생했던 error log (에러 해결 관련 nginx 설정 링크

upstream sent invalid chunked response while reading upstream, 

 

빨간선: ActiveOpens

파란선: PassiveOpens

평소 장애

큰 폭으로 감소했던 지표들을 요약하면

  • Nginx error 발생으로 신규 TCP 연결이 급격하게 감소 (나머지 지표는 그에 따른 영향으로 감소)

아... 그간 이 지표의 의미 해석을 미루고 미루고 미뤘는데 결과가 이렇게 허무하다니..

유입 고객이 늘어나서 터져나가는 장애를 겪어야 할텐데.. 코로나는 언제 지나가려나... 코로나가 간다고 손님이 늘긴하려나...

 

 

 

ActiveOpens

- TCP Client/Receiver (SYN을 보내고 SYN-SENT 상태가 된)

 

PassiveOpens

- TCP Server/Sender (SYN 받고 SYN-ACK 보내고 SYN-RCVD 상태가 된)

 

 

AttemptFails 

- TCP 연결이 SYN-SENT 상태 또는 SYN-RCVD 상태에서 CLOSED 상태로 곧 바로 전환된 횟수

- TCP 연결이 SYN-RCVD에서 LISTEN 상태로 바로 전환한 횟수

 

RetransSegs

- 재전송된 총 세그먼트 수(이전에 전송했던 하나 이상의 TCP 세그먼트를 포함하여 전송한 TCP 세그먼트 수)

 

 

반응형

'기타' 카테고리의 다른 글

테넌트  (656) 2020.07.23
TCP Status 상태에 대해서  (433) 2020.07.15
TCP 통계  (145) 2020.07.14
Kerberos Setup (KR)  (964) 2019.08.22
500 Error on Confluence Startup (KR)  (333) 2019.07.29

안녕하세요 쿤드입니다. 🍀

netstat --statistics 명령부터 시작해보겠습니다. (nstat 명령이 훨씬 간결하긴하지만..)

처음에는 각각의 인자들이 무엇을 의미하는지 확인하려고 했으나
이 페이지를 작성하다보니 하나씩 찾다보니 의미만 아는것은 별 필요가 없는것 같았습니다.

 

장애 당시를 기준으로 확인하는것이 좋을것 같아서 그때 확인한 factor들에 대해서

아래에 따로 정리해두었습니다.

작년에 제가 다니던 회사에서 중간에서 gateway역할을 해주는 application의 오류로 장애가 3시간정도 발생한적이 있었는데

그 당시 tcp 통계 변화를 바탕으로

내부적인 application 장애가 발생해서 외부에서 유입되는 traffic 처리를 못한 경우 어떤 차이가 발생하는지를 확인 해보도록 하겠습니다.

 

아래에 있는 내용들은 netstat으로 확인한 통계 값인데 

무엇을 의미하는건지 모르면 여기에 각각 설명이 잘 나와있습니다.

혹은 Linux Document

 

Ip:
    15829871449 total packets received (InReceives)
    0 forwarded (ForwDatagrams)
    0 incoming packets discarded (InDiscards)
    15829871405 incoming packets delivered (InDelivers)
    14182698760 requests sent out (OutRequests)
    31 outgoing packets dropped
    16 dropped because of missing route (OutNoRoutes)
    143 fragments failed
Icmp:
    12710040 ICMP messages received (InMsgs)
    167 input ICMP message failed. (InErrors)
    ICMP input histogram: 
        destination unreachable: 12263649 (InDestUnreachs)
        timeout in transit: 420248 (InTimeExcds)
        source quenches: 6 (InSrcQuenchs)
        redirects: 92 (InRedirects)
        echo requests: 26045 (InEchos)
    28937 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 2892 (OutDestUnreachs)
        echo replies: 26045 (OutEchoReps)
IcmpMsg:
        InType3: 12263649
        InType4: 6
        InType5: 92
        InType8: 26045
        InType11: 420248
        OutType0: 26045
        OutType3: 2892
Tcp:
    25768376 active connections openings (TcpActiveOpens)
    647707490 passive connection openings (TcpPassiveOpens)   
    4647341 failed connection attempts (AttemptFails)
    31117340 connection resets received (EstabResets)
    3537 connections established (CurrEstab) https://tools.ietf.org/html/rfc793   
    15817063195 segments received (InSegs)
    16491280655 segments send out (OutSegs)
    986318177 segments retransmited (RetransSegs)
    7440 bad segments received. (InErrs)
    91126171 resets sent (OutRsts)
Udp:
    95601 packets received (InDatagrams)
    2569 packets to unknown port received. (NoPorts)
    0 packet receive errors (InErrors)
    111544 packets sent (OutDatagrams)
    0 receive buffer errors (RcvbufErrors)
    0 send buffer errors (SndbufErrors)
UdpLite:
TcpExt:
    42045 SYN cookies sent (SyncookiesSent)
    12143 SYN cookies received (SyncookiesRecv)
    60209039 invalid SYN cookies received (SyncookiesFailed)
    4647134 resets received for embryonic SYN_RECV sockets (EmbryonicRsts)
    3821 packets pruned from receive queue because of socket buffer overrun (PruneCalled)
    63491 ICMP packets dropped because they were out-of-window (OutOfWindowIcmps)
    22286 ICMP packets dropped because socket was locked (LockDroppedIcmps)
    107834482 TCP sockets finished time wait in fast timer (TW)
    46352300 packets rejects in established connections because of timestamp (PAWSEstab)
    607439027 delayed acks sent (DelayedACKs)
    632566 delayed acks further delayed because of locked socket (DelayedACKLocked)
    Quick ack mode was activated 199302465 times (DelayedACKLost)
    208055 SYNs to LISTEN sockets dropped (ListenDrops)
    418093 packets directly queued to recvmsg prequeue. (TCPPrequeued)
    122606 bytes directly in process context from backlog (TCPDirectCopyFromBacklog)
    79146389 bytes directly received in process context from prequeue (TCPDirectCopyFromPrequeue)
    1574327100 packet headers predicted (TCPHPHits)
    402495 packets header predicted and directly queued to user (TCPHPHitsToUser)
    7766206385 acknowledgments not containing data payload received (TCPPureAcks)
    559462251 predicted acknowledgments
    24017 times recovered from packet loss due to fast retransmit
    72915270 times recovered from packet loss by selective acknowledgements
    586 bad SACK blocks received
    Detected reordering 889310 times using FACK
    Detected reordering 465211 times using SACK
    Detected reordering 697 times using reno fast retransmit
    Detected reordering 13789060 times using time stamp
    6344097 congestion windows fully recovered without slow start
    10638781 congestion windows partially recovered using Hoe heuristic
    1716234 congestion windows recovered without slow start by DSACK
    43272810 congestion windows recovered without slow start after partial ack
    TCPLostRetransmit: 1784385
    13185 timeouts after reno fast retransmit
    15322792 timeouts after SACK recovery
    26945066 timeouts in loss state
    104358514 fast retransmits
    30761536 forward retransmits
    72817949 retransmits in slow start
    189678472 other TCP timeouts
    TCPLossProbes: 324536377
    TCPLossProbeRecovery: 76481412
    12218 classic Reno fast retransmits failed
    27270545 SACK retransmits failed
    200116946 DSACKs sent for old packets (TCPDSACKOldSent)
    3581427 DSACKs sent for out of order packets 
    188637563 DSACKs received
    1897085 DSACKs for out of order packets received
    17269734 connections reset due to unexpected data (TCPAbortOnData)
    994645 connections reset due to early user close (TCPAbortOnClose)
    71206457 connections aborted due to timeout (TCPAbortOnTimeout)
    20 times unable to send RST due to no memory
    TCPSACKDiscard: 2614 (Number of SACK blocks are invalid)
    TCPDSACKIgnoredOld: 457719 (Number of DSACK block is invalid, undo_marker not set)
    TCPDSACKIgnoredNoUndo: 94644730 (Number of DSACK block is invalid, undo_marker set)
    TCPSpuriousRTOs: 3443956 (Number of The spurious retransmission timeout detected by the `F-RTO`_ algorithm)
    * skb: The linux networking stack stores data in sk_buff struct
    TCPSackShifted: 17209501 (Number of skb is shifted)
    TCPSackMerged: 57304616 (Number of skb is merged)
    TCPSackShiftFallback: 234570612 (Number of TCP stack doesn't merge it for some reasons.)
    TCPBacklogDrop: 43
    IPReversePathFilter: 3
    TCPReqQFullDoCookies: 42045
    TCPRetransFail: 271
    TCPRcvCoalesce: 606120335
    * OFO: Out Of Order
    TCPOFOQueue: 154893248 (Number of packets queued in OFO queue)
    TCPOFOMerge: 3581444 (Number of packets in OFO that were merged with other packets)
    TCPChallengeACK: 2105995
    TCPSYNChallenge: 64987
    TCPFastOpenCookieReqd: 3824
    TCPSpuriousRtxHostQueues: 332
    TCPAutoCorking: 19132
    TCPWantZeroWindowAdv: 6989
    TCPSynRetrans: 106752693 (Number of SYN and SYN/ACK retransmits to break down retransmissions into SYN,
                                                  fast-retransmits, timeout retransmits, etc.  참고링크)

    TCPOrigDataSent: 11168295644 (Number of outgoing packets with original data, 참고링크)
    TCPHystartTrainDetect: 97852 (Number of  the ACK train length threshold is detected)
    * CWND: Congestion Window
    TCPHystartTrainCwnd: 2647949 (The sum of CWND detected by ACK train length)
    TCPHystartDelayDetect: 21988563 (Number of the packet delay threshold is detected)
    TCPHystartDelayCwnd: 781061970 (The sum of CWND detected by packet delay)
    TCPACKSkippedSynRecv: 1717067 (If the ACk sending frequency is higher than tcp_invalid_ratelimit allows, then +1)
    * PAWS: Protect Against Wrapped Sequence numbers
    TCPACKSkippedPAWS: 1738488
    TCPACKSkippedSeq: 38312
    TCPACKSkippedFinWait2: 2294
    TCPACKSkippedTimeWait: 230801
    TCPACKSkippedChallenge: 8756
IpExt:
    InNoRoutes: 41
    InOctets: 8387403650946
    OutOctets: 12141527324794
    InNoECTPkts: 14298811581
    InECT1Pkts: 279253858
    InECT0Pkts: 271928848
    InCEPkts: 981945413

 

 

그런데 그 설명을 번역만 하는것으로는 도무지 뜬구름 잡는 얘기 같아서 하나도 이해가 가지 않습니다.

일단은 이 수치가 무엇을 의미하는지 먼저 알아보고

이 중에서 필요한것만 따로 모아서 다시 보아야 겠습니다.

 

TCP 통계는 TCP state diagram과 같이 봅니다.

 

TCP 통계를 카테고리화해서 묶어서 보면 한눈에 들어와서 tcp 통계 항목들이 좀 보입니다.
https://perthcharles.github.io/2015/11/10/wiki-netstat-proc/

그마나 찾긴했으나 제가 사용하는 OS와 다른지 통계 factor에 차이가 있습니다.

적당히 느낌만 가지고 넘어갑니다.

category Involve Counters
Realtime RtoAlgorithm、RtoMin、RtoMax、MaxConn
Connection ActiveOpens、PassiveOpens、AttemptFails、CurrEstab、EstabResets
Packet InSegs、OutSegs、RetransSegs、InErrs、OutRsts、InCsumErrors、EmbryonicRsts
syncookies SyncookiesSent、SyncookiesRecv、SyncookiesFailed
TIME_WAIT recycle TW、TWRecycled、TWKilled、TCPTimeWaitOverflow
RTO frequency TCPTimeouts、TCPSpuriousRTOs、TCPLossProbes、TCPLossProbeRecovery、
TCPRenoRecoveryFail、TCPSackRecoveryFail、
TCPRenoFailures、TCPSackFailures、
TCPLossFailures
Retrans Quantity TCPFastRetrans、TCPForwardRetrans、
TCPSlowStartRetrans、TCPLostRetransmit、
TCPRetransFail
FastOpen TCPFastOpenActive、TCPFastOpenPassive、
TCPFastOpenPassiveFail、TCPFastOpenListenOverflow、
TCPFastOpenCookieReqd
MD5 TCPMD5NotFound、TCPMD5Unexpected
DelayedACK DelayedACKs、DelayedACKLocked、DelayedACKLost、
TCPSchedulerFailed
DSACK TCPDSACKOldSent、TCPDSACKOfoSent、
TCPDSACKRecv、TCPDSACKOfoRecv、
TCPDSACKIgnoredOld、TCPDSACKIgnoredNoUndo
Reorder TCPFACKReorder、TCPSACKReorder、
TCPRenoReorder、TCPTSReorder
Recovery TCPRenoRecovery、TCPSackRecovery、
TCPRenoRecoveryFail、TCPSackRecoveryFail
Abort TCPAbortOnData、TCPAbortOnClose、
TCPAbortOnMemory、TCPAbortOnTimeout、
TCPAbortOnLingerTCPAbortFailed

 

 

 

반응형

'기타' 카테고리의 다른 글

TCP Status 상태에 대해서  (433) 2020.07.15
TCP 통계수치 변화 (장애 상황)  (1029) 2020.07.15
Kerberos Setup (KR)  (964) 2019.08.22
500 Error on Confluence Startup (KR)  (333) 2019.07.29
squid proxy  (4) 2018.12.19

감사(audit)에서 access control을 하는데 

centos 각 서버의 계정에 대해서 이를 관리하는것이 너무 불편한다.

Kerberos를 도입한다.

도입했던 이력을 아래에 정리한다.

 

목차

  • kerberos server
  • kerberos client
  • macos

Kerberos Server

Install

1. 작업 환경

$ cat /etc/system-release
Amazon Linux release 2 (Karoo)

2. 설치한 패키지 목록

  • krb5 관련
  • ntp
$ sudo yum list installed | grep krb
krb5-devel.x86_64                     1.15.1-19.amzn2.0.3            @amzn2-core
krb5-libs.x86_64                      1.15.1-19.amzn2.0.3            @amzn2-core
krb5-server.x86_64                    1.15.1-19.amzn2.0.3            @amzn2-core
krb5-workstation.x86_64               1.15.1-19.amzn2.0.3            @amzn2-core
pam_krb5.x86_64                       2.4.8-6.amzn2.0.2              @amzn2-core

$ sudo yum list installed | grep ntp
fontpackages-filesystem.noarch        1.44-8.amzn2                   @amzn2-core

참고링크

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/managing_smart_cards/installing-kerberos

https://gist.github.com/ashrithr/4767927948eca70845db

 

설정

1. EC2 인스턴스 2대 생성

- master, slave로 HA 구성했다.

 

2. DNS 설정

Route 53에 2개의 도메인을 추가했다. (abcdef.com은 실제 도메인이름으로 바꿔야함

- kdc.abcdef.com

- kdc2.abcdef.com

 

 

설정파일

 

1. /etc/krb5.conf 설정

- realm에 세팅할 도메인은 '대문자'로 해야한다.

$ cat /etc/krb5.conf
# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/

[logging]
 kdc = FILE:/var/log/kerberos/krb5kdc.log
 admin_server = FILE:/var/log/kerberos/kadmin.log
 default = FILE:/var/log/kerberos/krb5lib.log

[libdefaults]
 default_realm = ABCDEF.COM
 dns_lookup_realm = false
 dns_lookup_kdc = false
 rdns = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true

[realms]
 ABCDEF.COM = {
  kdc = kdc.abcdef.com:88
  kdc = kdc2.abcdef.com:88
  admin_server = kdc.abcdef.com:749
  default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4
  default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4
  permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4
 }

[domain_realm]
# .example.com = EXAMPLE.COM
# example.com = EXAMPLE.COM   

 

 

2. /var/kerberos/krb5kdc/kdc.conf 설정

[kdcdefaults]
 kdc_ports = 88
 kdc_tcp_ports = 88

[realms]
 ABCDEF.COM = {
  kadmind_port = 749
  max_life = 9h 0m 0s
  max_renewable_life = 7d 0h 0m 0s
  master_key_type = des3-hmac-sha1
  supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal arcfour-hmac-md5:normal
  database_name = /var/kerberos/krb5kdc/principal
  admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
  acl_file = /var/kerberos/krb5kdc/kadm5.acl
  dict_file = /var/kerberos/krb5kdc/kadm5.dict
  key_stash_file = /var/kerberos/krb5kdc/.k5.ABCDEF.COM
 }

 

 

3. /var/kerberos/krb5kdc/kadm5.acl 설정

*/admin@ABCDEF.COM  *

 

나머지 세팅

 

1. KDC database 생성

kdb5_util create -r ABCDEF.COM -s

 

 

2. KDC admin 생성

# kadmin.local
kadmin.local:  addprinc account/admin@ABCDEF.COM
     
NOTICE: no policy specified for "admin/admin@ABCDEF.COM";
assigning "default".

Enter password for principal admin/admin@ATHENA.MIT.EDU:  (Enter a password.)
Re-enter password for principal admin/admin@ATHENA.MIT.EDU: (Type it again.)

Principal "admin/admin@ABCDEF.COM" created.
 
kadmin.local:

 

 

3. KDC database 백업 (링크에 복구 방법도 있음)

#!/bin/bash

/usr/sbin/kdb5_util dump /var/kerberos/slave_datatrans


/usr/sbin/kprop -f /var/kerberos/slave_datatrans mgmt-krb-kdc02.abcdef.com > /dev/null
  • 참고로 전달할 도메인 정보는 /etc/hosts에 있다.
% cat /etc/hosts

... 
10.100.125.156     mgmt-krb-kdc02.abcdef.com mgmt-krb-kdc02

 

4. 데몬 설정

systemctl start krb5kdc.service
systemctl start kadmin.service
systemctl enable krb5kdc.service
systemctl enable kadmin.service

 

Kerberos Client

Install

yum --disablerepo=*  --enablerepo=base,update install -y dmidecode krb5-libs

설정

참고로 ec2 1대에 nginx를 두고 스크립트를 불러다가 client로 동작할 서버에 세팅을 한다. 
대략 이런 명령을 이용함
curl -s krb5-client.abcdef.com/seeds/krb-svr-config | /bin/bash

위의 ec2에 flask로 간단하게 구현한 api 서버를 두고 잡다한(계정 추가, 변경, 삭제, ...) 처리를한다.

파일설정

1. /etc/hosts 설정 

  • 필요에 따라서 설정한다.

2. /etc/ssh/sshd_config 설정

  • 필요에 따라서 설정한다.

3. ntp update 수행

ntpdate -u pool.ntp.org

4. kadmin에서 신규 서버 principal 등록, keytab 생성

# addpric
/usr/bin/kadmin -p account/admin -w RkaWkrdldi -q "addprinc -randkey host/dev1-api-all.abcdef.com"

# ktadd
/usr/bin/kadmin -p account/admin -w RkaWkrdldi -q ktadd -k "/home/ec2-user/seeds/keytabs/dev1-api-all.abcdef.com host/dev1-api-all.abcdef.com"

# chmod
chmod og+r /home/ec2-user/seeds/keytabs/dev1-api-all.abcdef.com

5. kdc hosts 파일에 등록

cat /home/ec2-user/seeds/hosts

10.100.56.52      dev1-api-lucky21.abcdef.com       dev1-api-lucky201              
10.100.56.51      dev1-api-lucky11.abcdef.com       dev1-api-lucky101              
10.100.56.50      dev1-api-lucky01.abcdef.com       dev1-api-lucky001              
10.100.56.21      dev1-api-point11.abcdef.com     dev1-api-point101                
10.100.56.22      dev1-api-point12.abcdef.com     dev1-api-point12                 
10.100.56.20      dev1-api-point01.abcdef.com     dev1-api-point001                
10.100.56.23      dev1-api-point21.abcdef.com     dev1-api-point201                
10.100.56.24      dev1-api-point22.abcdef.com     dev1-api-point22                 
10.100.0.162      dev1-proxy-out21.abcdef.com        dev1-proxy-out201             
10.100.0.161      dev1-proxy-out11.abcdef.com        dev1-proxy-out101    

6. 이번엔 4단계에서 생성했던 keytab 파일을 실제 kerberos client에 복사해둔다.

/etc/krb5.keytab

 

addprinc, ktadd 이렇게하고 생성한 keytab 파일을 kerberos client에 옮겨두어야 한다. 

그리고 그와 관련해서 hosts 파일도 갱신해야한다.

이를 좀 편리하게 하기 위해서 ec2에 nginx + gunicorn + flask로 구성한 api 서버를 두고 처리하고 있다.

 

MacOS 사용자 설정

내 pc에서 ssh로 접근할 때 사용할거라서 내거에도 설정해야한다.

 

1. /etc/krb5.conf 설정

[libdefaults]
default_realm = ABCDEF.COM
allow_weak_crypto = false
rdns = false

[realms]
ABCDEF.COM = {
kdc = kdc.abcdef.com
kdc = kdc2.abcdef.com
admin_server = kdc.abcdef.com
kpasswd_server = kdc.abcdef.com
}

 

2.  /etc/ssh/ssh_config 설정

  • 참고로 MacOS update 하고나면 이 설정이 원복 되기도 하므로 update 이후엔 확인 해보아야 한다.
GSSAPIAuthentication yes    => Allow authentication protocol for ssh kerberos support
StrictHostKeyChecking no     

3. MacOS의 터미널에 접속해서 kinit을 한다.

kinit --kdc-hostname=kdc.abcdef.com,kdc2.abcdef.com sfixer@ABCDEF.COM

그리고 나서 제대로 되는지 확인한다.

% ssh sfixer@10.100.125.143
% ssh sfixer@dev1-api-all
...
반응형

'기타' 카테고리의 다른 글

TCP 통계수치 변화 (장애 상황)  (1029) 2020.07.15
TCP 통계  (145) 2020.07.14
500 Error on Confluence Startup (KR)  (333) 2019.07.29
squid proxy  (4) 2018.12.19
reverse proxy 개념  (6) 2018.12.19

+ Recent posts