코인 자동매매 만들기 #2 업비트 API 401 no_authorization_ip 해결하는 법

코인 자동매매 만들기2편 중 2번째

curl ifconfig.me는 IPv6를 돌려줄 수 있고 업비트 허용 IP는 IPv4만 받는다. 등록할 주소는 -4를 붙여 뽑고, 막힌 원인은 401 본문의 Request IP로 확인한다.

어제 업비트 허용 IP 목록에 주소 한 줄을 넣고 봇을 다시 올렸다. 퇴사하고 AI로 회사를 만드는 중이고, 굴리는 것 중 하나가 예산 29만원으로 도는 업비트 실거래 매매 봇이다. 그 등록이 하루를 못 갔다.

8시간 45분

아침 7시 30분부터 401이 다시 찍히기 시작했다. 인증 감시 스크립트는 5분마다 계좌를 조회해보고 통과하면 봇을 스스로 다시 올린다. 그날 그 로그에 남은 건 네 줄이다. 막혀 있다, 막혀 있다, 막혀 있다, 그리고 마지막 줄에서 통과해 봇을 다시 올렸다.

복구는 자동으로 됐는데 알림이 없었다. 막혀 있다는 사실을 8시간 45분 동안 몰랐다. 그동안 401 카운트는 969까지 올라갔다.

IP가 바뀐 줄 알았다

가장 그럴듯한 설명은 회선의 공인 IP가 바뀌었다는 것이었다. 이 회선은 실제로 주소가 바뀐다. 사흘 전 백업 파일에 등록돼 있던 주소는 121.172.87.6이고 지금은 58.29.51.120이다. 그 전에 쌓여 있던 401 로그 4.1MB는 이걸로 설명된다.

이번엔 달랐다. 401 본문을 처음으로 끝까지 읽었더니 답이 거기 적혀 있었다.

RuntimeError: GET /v1/accounts -> 401
{"error":{"message":"The request was made from an unregistered IP
address. Request IP: 58.29.51.120","name":"no_authorization_ip"}}

업비트가 본 출발지가 본문에 들어 있다. 지금 이 맥이 쓰는 주소와 같은 값이다. 추측이 아니라 막은 쪽이 보낸 문장이다. 이번 401은 주소가 바뀌어서 난 게 아니었다.

나머지 가설도 하나씩 잘랐다. 업비트 도메인은 AAAA 레코드가 없어서 IPv6로 나갈 수 없고, 확인 서비스 네 곳에서 연속으로 재도 전부 같은 주소가 나오고, 시스템 전원 로그에 7시대 절전 이벤트는 0건이고, API 키는 2027-09-17까지 361일 남아 있었다.

등록하라고 찍어주던 값이 등록할 수 없는 값이었다

가설을 자르는 동안 다른 게 걸렸다. 키를 등록할 때 쓰는 스크립트가 “허용 IP에 넣을 값”이라며 주소를 화면에 찍어주는데, 그 값을 ifconfig.me에 물어서 가져온다. 이 맥에서 그게 주는 값은 이렇다.

$ curl -s https://ifconfig.me   → 2406:5900:104d:4014:c9b1:962e:8852:17d
$ curl -s -4 https://ifconfig.me   → 58.29.51.120

콜론이 든 위쪽이 IPv6다. 업비트 문서가 허용 IP에 대해 적는 것은 세 가지뿐이다. 공인 IP만, IPv4 형식만, 유동 IP는 권장하지 않음. 스크립트가 넣으라고 찍어준 값은 등록 폼이 받지도 않는다. 봇이 인증에 실패했을 때 나오는 안내문에도 같은 명령이 적혀 있었다. 쓸 수 있는 값과 넣지도 못하는 값을 가른 것이 -4 두 글자다.

허용 IP 목록에 자기 주소를 넣어야 하는 서비스를 쓴다면, 주소를 뽑는 명령에 -4를 붙이세요. 콜론이 든 값이 나오면 그건 그 폼에 넣을 수 없는 값입니다.

고친 건 두 군데다. 주소를 뽑는 함수는 IPv4만 주는 호스트 두 곳으로 바꾸고 콜론이 든 값은 버리게 했다. 실패 안내문은 401 본문에서 Request IP를 뽑아 그대로 보여주도록 바꿨다. 외부 서비스에 내 주소를 묻지 않고 막은 쪽이 본 주소를 쓴다.

원인은 여기서 끊긴다

등록이 왜 풀렸는지는 끝내 못 밝혔다. 남은 설명은 “업비트 등록 목록에서 이 주소가 빠졌다” 하나인데 확인할 방법이 없다. 키 조회 API는 access_key와 만료일만 돌려주고 허용 IP 목록은 안 준다. 공식 문서에도 허용 IP가 자동으로 풀린다는 서술이 없다. 기간도 조건도 적혀 있지 않다. 다음에 또 나도 나는 같은 자리에서 끊긴다.

그래서 원인 대신 감지를 고쳤다. 인증 감시 스크립트가 막힘으로 바뀔 때 한 번, 그 뒤 6시간마다 한 번, 복구될 때 한 번 텔레그램을 보낸다. 5분마다 도는 스크립트라 같은 알림이 반복되지 않게 상태 파일 하나로 전환만 잡는다. dry-run 6단계 중 두 번째 칸이 처음에 실패했다. 첫 알림 5분 뒤에 “아직 막혀 있다”가 한 번 더 나갔고, 리마인드 시계를 첫 감지 때 같이 맞춰두는 것으로 고쳤다.

텔레그램이 실제로 도착하는지는 확인하지 않았다. 문안과 트리거 조건만 봤다. 메시지에는 업비트가 본 요청 IP와 “등록되면 5분 안에 봇이 스스로 다시 올라간다”가 들어간다.

장부 원화 260,436원과 실잔고 270,403원의 차이 9,967원은 아직 설명하지 못했다.

← 전체 글