ROS2는 현재도 계속 개발 중으로 다양한 배포판이 나오고 있다. 이 중 Humble 배포판의 설치 내용을 정리한다.

 

윈도우로 설치하고자 한다면 아래와 같이 Microsoft Store에서 Ubuntu 22.04 LTS 버전을 다운로드 받고, 리눅스로 설치하고자 한다면 우분투 22.04에서 아래 나올 설치과정을 수행하면 된다.

 

1. ROS 설치

1.1 우분투 업데이트 및 언어 설정을 위한 locale 설치

sudo apt update && sudo apt install locales

 

1.2 locale 세팅

sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

 

1.3 ROS2 설치를 위한 universe 저장소 활성화

apt-cache policy | grep universe

 

1.4 ROS2 apt 저장소를 시스템에 추가 & GPG 키 승인

sudo apt update && sudo apt install curl gnupg lsb-release
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

 

1.5 ROS2 저장소를 sources.list에 추가

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

 

1.6 sources.list 업데이트에 따른 우분투 시스템 update 수행

sudo apt update
sudo apt upgrade

 

1.7 ROS2 설치 (다른 설치 과정에 비해 상대적으로 많은 시간 소요)

sudo apt install ros-humble-desktop

만약 풀버전을 다운로드 받고 싶다면 sudo apt install ros-humble-desktop-full 명령을 실행할 것. (차이점 파악 필요..)

 

1.8 ROS2 동작에 필요한 패키지 설치 (통신 라이브러리, CLI 도구 등 포함)

sudo apt install ros-humble-ros-base

 

2. ROS2 설치 검증

검증 1 - 통신 가능 여부

ROS2의 'Hello World'를 통해 정상적으로 설치되었는지를 확인한다. 이는 두 개의 터미널로 데이터를 주고 받는 것이 가능한지를 확인함으로써 가능하다. Talker와 Listener가 있고 Talker가 터미널에서 출력하는 메시지를 Listener가 받아서 그대로 출력할 수 있는지를 검증한다.

 

Talker 실행 (C++ 기반)

source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp talker

 

Listener 실행 (Python 기반)

source /opt/ros/humble/setup.bash
ros2 run demo_nodes_py listener

 

(ROS2는 C++과 Python을 함께 지원한다.)

 

위 명령들을 실행하면 두 터미널에서 다음과 같은 형태로 Talker가 출력한 값을 Listener가 받아와 그대로 출력하는 것을 확인할 수 있다.

 

매번 source /opt/ros/humble/setup.bash를 입력하는 것이 귀찮으니 .bashrc 파일에 넣어 터미널이 실행될 때 자동으로 실행되도록 하자

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc

 

검증 2 - 패키지 빌드 가능 여부

ROS2에서 패키지를 빌드하는 명령이 잘 수행되는지 여부를 판단하여 ROS2가 정상적으로 설치되었음을 확인한다.

soruce ~/opt/ros/humble/setup.bash
mkdir -p ~/robot/src/
cd ~/robot
colcon build --symlink-install

 

위 명령을 수행하면 다음과 같이 기존의 src 폴더와 더불어 build, install, log가 생성되며 이와 같이 생성된다면 ROS2가 정상적으로 설치된 것이다. 

아래는 동일한 내용으로 위와 같이 WSL이 아니라 Ubuntu 22.04를 설치하여 빌드 가능함을 확인하였다.

 

3. Gazebo 설치

Gazebo는 시뮬레이션 환경이다. 개발한 로봇 관련 알고리즘을 하드웨어에 적용시키기 이전에 소프트웨어적인 시뮬레이션을 통해 정상적으로 동작하는지 검증하기 위해 사용한다. 실제와 같이 중력, 기압, 고도, 풍속 등의 요소 등을 적용하여 시뮬레이션 할 수 있다. Gazebo이외에 MS에서 만든 Airsim이나 JMavSim도 있지만 상대적으로 레퍼런스가 많아 개발에 조금 더 용이한 Gazebo를 설치한다. 참고로 아래는 오픈소스 시뮬레이터 비교 표다. 

3.1 gazebo 설치

sudo apt-get -y install gazebo

(만약 gazebo 설치가 정상적으로 이뤄지지 않은 것 같다면 아래 명령 수행 - 차이점 파악 필요...)

sudo apt install ros-humble-gazebo-ros

 

위 명령을 통해 gazebo를 설치하고 난 뒤 다음과 같이 명령어를 수행하면 아래와 같이 Gazebo 시뮬레이터가 실행된다.

gazebo --verbose

 

 

만약 Failed to execute child process "dbus-launch" 에러가 발생하면 dbux-x11 패키지를 설치해줄 것

sudo apt install dbux-x11

 

4. ROS2 시각화 툴 설치 확인

ROS2에서 이뤄지는 통신 과정이나 시뮬레이션 상황을 시각화해서 보아야 할 때가 있다. rviz2가 시각화 도구다. ROS2 패키지 설치시 함께 설치된다. 아래와 같이 터미널에 rviz2를 실행하면 시각화 프로그램이 실행됨을 확인할 수 있다.

 

5. ROS2 개발 툴체인 설치

sudo apt update && sudo apt install -y build-essential cmake git libbullet-dev python3-colcon-common-extensions python3-flake8 python3-pip python3-pytest-cov python3-rosdep python3-setuptools python3-vcstool wget
python3 -m pip install -U argcomplete flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes pytest-repeat pytest-rerunfailures pytest
sudo apt install --no-install-recommends -y libasio-dev libtinyxml2-dev libcunit1-dev

 

6. 기타 패키지 설치

# ROS2-gazebo 연동을 위한 패키지
sudo apt install ros-humble-gazebo-ros-pkgs
sudo apt install ros-humble-gazebo-ros2-control

# SLAM 관련 패키지 
sudo apt install ros-humble-cartographer
sudo apt install ros-humble-cartographer-ros

# Navigation 관련 패키지
sudo apt install ros-humble-navigation2
sudo apt install ros-humble-nav2-bringup

# ROS2 motion planning 프레임워크
sudo apt-get install ros-humble-moveit

# pyqt 설치
sudo apt-get install pyqt5-dev-tools
python3 -m pip install --upgrade pip
python3 -m pip install -U catkin_pkg cryptography empy ifcfg lark-parser lxml netifaces numpy opencv-python pyparsing pyyaml setuptools rosdistro
python3 -m pip install -U pydot PyQt5

 

Reference

[1] https://makingrobot.tistory.com/159

[2] https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html

[3] https://omorobot.gitbook.io/manual/product/omo-r1mini/ros/ros2-foxy/ros2-ubuntu-20.04

[4] https://keep-steady.tistory.com/45

[5] https://puzzling-cashew-c4c.notion.site/ROS-2-Foxy-Windows-10-WSL-2-f50188cdf0c540119defa69fb40db221


더 나은 세상을 위해 살고 싶단 내 바람은 자본주의 시스템으로부터 더욱 심화된 빈곤이란 주제에 관심을 두게 했다. 나는 궁금했다. 사회적 빈곤은 정말로 해결할 수 없는 문제인가? 사회적 빈곤이 나타나는 구조적 원인은 무엇인가? 또 빈곤의 배태로부터 비롯되는 문제점과 지금 현 대응책은 무엇인가?

이 책은 이런 빈곤에 대한 거시적인 물음에 대한 답이라기보다 사회 문제에 대해 잘 알지 못하는 나 같은 사람에게도 쉽게 이해할 수 있도록 미시적 관점으로 가난의 한 모습을 비춰줌으로써 그 이해를 높일 수 있는 책이었다. 이 책은 재활용품을 수집하고 판매하는 노인들을 중점으로 이들이 처한 상황과 배경, 일상을 4년간 조사하고 연구한 내용을 바탕으로 쓰여졌다.

재활용품을 수집하고 판매하는 소위 가난한 사람들 대다수가 노인층으로 구성되어 있다. 그렇다면 이 노인층 중 재활용품을 수집하고 판매하는 사람들은 왜 가난하게 되었는가? 이러한 노인의 가난 원인은 여러가지가 있지만 가장 먼저 현재의 노인이 1930년 중반에서 1950년 중반에 태어났고, 1980년말 시행된 사회보험제도에서 제외된 처지라는 것이다. 때문에 안전망이 구비되고 노후를 준비할 수 있었던 이후 세대와 달리 자력갱생을 요구받는 상태이다. 또, 사회와 기술의 발전 때문이다. 이로 인해 전통적으로 지식창고 역할을 하던 노인이 책과 인터넷으로 대체되며 그 쓸모가 변했다는 것이다. 또 기초수급자 지정조건 때문이다. 이 조건은 '가족'의 소득과 재산이 일정 기준을 넘지 않아야 하지만 연락이 끊긴 자식의 경제수준이 기준 이상이기에 정부의 지원을 받을 수 없게 된다. 또 노인은 한국사회에서 임금노동 시장이나 공공근로 일자리에서 배제되어 있기 때문이다. 특히 여성 노인은 구직이 매우 어렵다. 가사도우미나 음식업 외에 많지가 않다. 때문에 결과적으로 돈을 벌 수 있는 유일한 방법인 재활용품 수거로 내몰리게 되는 것이다.

이 재활용품 수거라는 산업과 사회의 끝자락에 내몰린 일엔 노동의 그 어떤 정당성도 안정성도 바랄 수 없다. 하루종일 걷고 걸어 100kg~200kg 가량의 재활용품을 수집하더라도 겨우 단돈 8,000~9,000원도 안되는 수준의 대가를 받는다. 또 재활용품을 담기 위해선 리어카가 필요하다. 하지만 여성노인은 50kg가 나가는 리어카의 무게를 감당하기 힘들 뿐더러 재활용품이 더해진 무게는 견딜 수도 없다. 또 경쟁과 약탈이 있어 여성노인이 발견한 재활용품을 남성노인이 가로채는 경우도 있다. 이들은 신체경쟁에서 불리하며 쓰라린 패배감을 느끼게 된다. 또 용변을 보기 위해 세워둔 리어카나 카트를 도난당하기도 한다. 또 리어카를 끌다 주차차량과 부딪히면 수리비를 물어야 하고 과속방지턱을 넘다가 재활용품이 쏟아지기도 한다. 그리고 리어카를 끌기 위해 금속과 맞닿는 신체의 피부는 멍과 굳은 살로 덮힌다. 또 일부 건물주는 건물을 청소하는 대가로 재활용품을 가져갈 수 있도록 유사 고용을 하며 이에 따른 금전 대가를 지불하지 않는다.

이러한 궂은 상황에서 받는 돈은 한 끼 밥값이 채 되지 않는다. 일을 해도 가난을 벗어날 수 없는 처지인 것이다. 실제로도 우리 한국의 노인 고용율은 OECD 가입 국 중 가장 높다. 또 OECD 국가 중 노인의 상대적 빈곤율은 43.8%로 가장 높다. 즉 일을 많이 해도 빈곤하다는 것이다. 이러한 문제점을 해결하기 위해 내놓는 사회에서 이뤄지고 있는 현 대응책은 무엇이 있을까?

가장 먼저 노인일자리사업이다. 보건복지부에선 노인일자리 활동지원사업을 한다고 한다. 하지만 참여자 선발과정에서 치열한 경쟁이 필요하다. 또 참여자들은 월 평균 27만원씩 받았고 참여하지 않은 사람은 12만원씩 받지만 이 사업을 통해 노인의 상황이 실질적으로 나아졌다고 볼 수 없다. 이외에 사회적기업이나 협동조합에서 노인일자리 제공이다. 하지만 이러한 조직이 사업을 성장시키거나 지속성을 유지하는 경우가 매우 적다. 또 경로당을 공동작업장으로 바꾼 시도도 있다. 노인에게 쇼핑백 제조, 상품 포장 및 배달, 취약가구 무료 세탁, 먹거리 제조 등이다. 노인일자리와 부가가치 창출이란 긍정적인 측면도 있지만 여전히 참여하지 못하고 소외되는 이들이 존재한다.

저자는 정부가 이러한 노인일자리사업을 만들고 장려하지만 상황이 나아지지 않음을 짚는다. 즉 일자리의 질이 낮고, 또 낮을 수 밖에 없다고 말하며 사실상 재활용품 수집 노인의 일을 다른 것으로 전환시킬 방법은 없다고 말한다. 따라서 우리가 해야할 일은 노인들이 일을 하지 않고도 행복할 수 있는 방법을 마련하는 것이라 말하며 궁극적으로 노인들이 더 나은 기초소득을 가질 방법을 고민해야 한다고 말한다.

이 책을 통해 국가나 기업차원에서 이뤄지는 노인일자리사업으로도 불충분하다는 것을 여실히 알게 되었다. 사회적 빈곤이 사라진 세상은 가능할까? 지속적으로 변화를 거듭하는 인류에게 있어 새 문제가 발생하면 기존에 존재하는 이러한 빈곤과 같은 문제는 해결하기 어려울 수도 있을 것이다. 하지만 완전할 수 없다면 최소화시키는 노력은 할 수 있을 것이다. 이를 위해 국가 정책이나 지역 정책을 통해 저소득층을 지원하고 일자리를 창출하고, 주거, 의료, 교육의 기회를 주어 어려운 사람들에게 최소한의 삶의 질을 보장해야 한다. 현재로서의 효용성은 미비하나 그럼에도 이를 진전시키기 위한 우리의 걸음은 멈추지 않아야 할 것이다.

마음에 남는 대목

  • 이제는 가난의 문법이 바뀌었다. 도시의 가난이란 설비도 갖춰지지 않은 누추한 주거지나 길 위에서 잠드는 비루한 외양의 사람들로만 비춰지지 않는다.
  • 노인들의 삶이 순전히 개인의 잘못 때문에 생겨나는 걸까? 가난하고 싶어서 가난해진 사람은 없다.
  • 국가는 헌법에서 개인이 가지는 인권을 보장할 의무가 있음을 밝히고 있다.
  • 궁극적으로는 노인들이 재활용품을 줍지 않는 사회로 변화시켜 나가야 할 것이다.
  • 가난한 노인의 문제는 연민과 감동 그리고 자선 사업으로 해결 되지 않는다. 정작 필요한 건 안전한 자선활동이 아니라 현실에 대해 인식하고 실질적인 변화를 만드는 것이다.
  • 우리는 누군가의 가난을 보며 사회 체제의 불안정함과 미비함을 깨닫는 것처럼 보이지만, 그 깨달음은 사회를 바꾸어야 한다는 결론이 아니라 스스로의 상대적 안정감을 확신하고 불안정에 대한 두려움을 상기하는 것으로 이어질 따름이다.


2023년 첫 번째 독서다. 64권을 읽은 작년과 비교해 올해는 얼마나 읽게 될지 올해 말이 궁금해진다. 이 책은 맥도널드를 프렌차이즈 시스템으로 만들기 위해 도전했던 레이크록의 일화다. 종이컵을 파는 세일즈맨으로부터 시작해 맥도널드의 최고경영자까지 올라가는 과정에서 레이크록의 기업가 정신을 엿 볼 수 있어 좋았다. 다만 아쉬웠던 점은 이 책에서 강조하는 가치들은 지금에 이르러서 식상해진 가치가 아닌가라는 생각도 들었다. 이 책이 우리 인생의 바이블이라 했던 소프트뱅크 손정의 회장의 추천사가 있어 기대를 했지만 책이란 무릇 독자의 배경과 관심사에 따라 달리 느껴질 수 있음을 다시 한 번 느끼게 됐다. 아래는 책을 읽으며 밑줄 그었던 내용을 요약한 내용이다.

- 새 아이디어를 낼 때 처음부터 원대한 구상을 하지 않는다. 부분에서 전체로 나아갈 뿐이다.
- 단순해 보일 지언정 디테일의 중요성을 강조한다.
- 재능 있지만 성공하지 못한 사람이 많다. 이름값 못하는 천재도 많다. 또 세상엔 고학력의 낙오자로 가득하다. 전능의 힘을 가진 것은 끈기와 투지 뿐이다.
- 점포 입지와 점포 개발이 중요하다.
- 경쟁자를 이기려면 같은 입지에서 싸우는 것이 아니다. 자신만의 새 입지를 다져야 한다.
- "단, 비서님이 판단하지 말아주세요."
- 민주사회엔 미디어란 사회적 시스템이 필요하다. 잘못을 저지르는 개인과 회사에 경고를 보내기 위함이다. 아프지만 없다면 사회전체에 위기가 올 수 있다.
- "사장님 그건 틀렸습니다"라고 말할 수 있는 회사가 되어야 한다 - 야나이
- "전 창의력을 발휘하는 사람입니다. 회사에 돈을 벌어다 준단 말입니다. 다른 사람과 같은 취급 받을 생각없습니다" - 레이크록
- "나는 돈 보다도 진정한 참여의식을 느낄 수 있는 일자리를 찾고 있었다. 하지만 그런 일자리는 없었다." - 레이크록
- 나를 팔아야 물건도 팔 수 있다. 가장 먼저 팔아야 하는건 우리 자신이다.
- 위험 없는 성공 없다.
- 나는 문제에 압도되지 않는 법을 배웠다. 한 번에 한 가지 이상은 걱정하지 않았다. 문제가 있어도 불필요하게 조바심 내지 않으려 했다.
- 그녀의 그 강인함을 다감하고 따뜻한 성격이 감싸고 있었다. 좀처럼 조화를 이루기 힘든 덕목을 모두 가진 것이다.
- 모르는 게 있다면 도서관 책 모두를 뒤져서라도 알아내곤 했다.
- 매장을 오픈한 경험에 비추면 관건은 속도다.
- 그 사람의 능력을 믿지 못하면 애초 고용하지 말아야 한다.
- 돈 벌기 위해 돈 써라.
- 아무리 기민한 판단도 다른 사람에겐 독단으로 비칠 수 있다.
- 한 페이지짜리 제안서였지만 담긴 논리는 반박할 수 없었다. 광고효과, 장기적손해 등이 모두 기술 돼 있었음
- 정상의 자린 외롭다. 상실감만 남는다.
- 고객은 지불하는 비용에 걸맞는 서비스를 누려야 한다.
- 보통 재단을 세금 도피처라 생각한다.
- 일하는 즐거움, 일해야 하는 즐거움을 깨닫는 법을 배워야 한다.
- 미국 독립선언문에도 적혔듯 '우리'가 할 수 있는 최선은 행복을 추구할 자유를 주는 것이었다. 행복은 성취의 부산물이다.

문제 상황

Node JS에서 MySQL에 Update 쿼리를 날렸을 때 당최 쿼리가 반영되지 않았다. 나의 경우에는 HTML selectbox에서 A, B, C 값 중 하나를 선택하면 ajax를 이용해 MySQL에 업데이트하는 간단한 기능을 구현하고 싶었다. 하지만 업데이트 되지 않았고 결과를 출력해보니 아래와 같이 출력됐다.

 

OkPacket {
  fieldCount: 0,
  affectedRows: 0,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '(Rows matched: 0  Changed: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0
}

 

쿼리는 에러없이 실행되었지만 중요한 것은 Rows matched: 0 Changed: 0이라고 출력된 부분이다. 분명 쿼리 실행 이전, selectbox에서 값도 잘 받아왔고 쿼리문도 문제 없이 작성했지만 결과에 반영 되지 않았다. 직접 MySQL Workchbench로 값을 수정하면 반영이 잘되었고, 권한 문제도 없었기에 원인을 더욱 찾지 못해 아까운 시간 하루를 시간을 낭비했다.

 

에러 해결 방법

원인은 쿼리였다. 늘 사용했었고 다른 기능 구현에도 원활히 실행 됐었기에 문제가 없을 것이라 생각했다. 사용했던 쿼리는 다음과 같다.

const query = `UPDATE users SET column = ? WHERE username = ?`
return new Promise((resolve, reject) => {
	db.query(query, [value, username], (error, result) => {
    	if (error)
        	throw (error);
        else
        	reject(true);
    })
})

하지만 위와 같은 구문을 사용할 것이 아니라 아래와 같이 변경할 컬럼과 값, 조건문과 조건값을 별도의 변수에 담은 뒤 입력해주어야 한다.

const values = {'column': value};
const condition = {'username': username};
const query = `UPDATE users SET ? WHERE ?`;
return new Promise((resolve, reject) => {
    db.query(query, [values, condition], (error, result) =>{
        if (error)
            throw (error);
        else
            resolve(true);
    })
})

 

위와 같은 구문을 사용해 Update 문을 실행하면 아래와 같이 업데이트가 이루어지는 것을 확인할 수 있다.

 

 

애석하게도 원인의 본질적인 문제는 찾진 못했다. 다만 SQL Injection 방지를 위해 '?'를 사용해 쿼리를 실행하는 prepared statement와 관련이 있는 것으로 보인다. 구글에서 해결 방법을 찾기 어려워 혹시나 하는 마음으로 ChatGPT에게 질의한 결과로 얻은 해결방법이었다. 에러는 해결했지만 마음 한 구석에 세상의 발전에 대한 환희감과 동시에 인간의 지위에 대한 박탈감을 느꼈다. 단순히 이 문제에 대한 해답만이 아니라 여러 학문에 대한 답과 철학적인 질문들에도 막힘없는 대답을 들을 수 있었기 때문이다. ChatGPT가 열어갈 미래와 변화할 사회 모습이 궁금해지는 대목이다.

최근 많은 Redis 서버가 해킹당해 악성 봇넷으로 사용되고 있다고 한다. 그 이유는 Redis 서버에 인증없이 접속할 수 있다면 Redis 내부 명령어를 통해 악성코드를 실행할 수 있기 때문이다. 최근 Node JS로 개발 중인 서비스에서 캐시 DB로 Redis를 설치해 사용했다. 로컬에서 사용하니 실제로 서버 운영할 때 보안설정 하면되겠거니와 하며 인증없이 접속할 수 있도록 했었다. 하지만 로컬에 설치했던 Redis는 기본적으로 모든 네트워크와 연결 수립을 허용하는 것을 인지하지 못한 오판이었다. Redis는 기본 포트로 6379를 사용한다. 해커들은 6379 포트가 열린 IP를 브루트포싱하며 악성코드 실행을 위해 지속적으로 Redis 서버를 스캐닝 중에 있다. 다음과 같이 말이다.

 

 

redis-cli.exe를 통해 'monitor' 옵션을 설정해주면 내 Redis 서버를 스캐닝하는 외부 IP와 PORT를 확인할 수 있다. 또 만약 외부 IP에서 내 redis 서버에 임의의 key와 value를 설정하면 위 모니터링에 의해 값 설정 로그가 출력된다. 해커는 Redis 서버에 저장된 key-value를 탈취할 수 있지만, 휘발성격의 중요성이 떨어지는 데이터를 담는 Redis에선 key-value 탈취로 인한 피해보다 value에 악성페이로드를 담아 실행했을 때의 피해가 더 클 수 있다. 

 

위 info 로그는 "redis-cli -h <IP> -p 6379 info" 명령을 수행하면 발생하는 로그다. 실제로 실행해보면 아래와 같이 서버, 클라이언트, 메모리, CPU 등의 각종 정보를 조회할 수 있다. 세부적으로 운영체제 정보나 설정파일 경로를 획득할 수 있으니 해커 입장에서 이후에 페이로드 구성에 활용할 수 있다.

 

 

위 각종 정보를 살펴보던 도중 Clients 영역에서 connected_clients가 3인 것을 볼 수 있었다. 로컬에서 사용했는데 연결된 클라이언트가 존재할 수 있는지 궁금해졌다. client list라는 명령어가 있었고 이를 통해 살펴보니 모르는 외부 IP와 연결되어 있었다. (나머지 2개는 실행했었던 redis-cli monitor와 redis-cli client였다.)

 

IP 주소를 조회해보니 어디 상하이가 찍혀 나왔다. 사이트에 들어가보니 e-commerce 관련 회사 홈페이지였고 C&C 서버로 쓰이고 있는 것 같다. 

 

 

연결을 끊어줘야겠단 생각이 들었고 찾아보니 clinet kill 명령이 존재했다. 이를 통해 아래와 같이 중국 IP와의 연결을 끊어주었다.

 

 

이렇게 Redis 서버 보안에 주의를 돌리게 된 이유는 크게 두 가지다. 첫 번째는 지난밤 PC에서 비프음 보다 더 강렬한 소리가 났다. 이게 무슨 소리지?라고 어떻게 하면 이런 소리가 나지?라고 생각했다. 간단하게 윈도우 디펜더를 돌린 결과 아무 이상 없어 넘어갔다. 하지만 두 번째로 오늘 인증없이 접속 가능한 Redis 서버가 많고 많은 서버가 봇넷으로 사용되고 있음을 알게 됐다. 혹여 지난밤 소리와도 관련있지 않을까하여 Redis에 설정된 key 값과 운영체제에서 남기는 여러 로그를 분석해보았지만 다행히도 의심되는 흔적은 발견되지 않았다. 털리진 않았지만 이후 보안 설정도 개발과 병행해야겠단 생각으로 이어지게 됐다. 

 

따라서 보안 설정 방법을 알아보던 중 KISA가 발간한 클라우드 취약점 점검 가이드에 Redis 시스템 취약점 점검 가이드가 있었고, 가이드에서 말하는 4가지 보안 설정을 해주었다. 첫 번째는 Redis 인증 패스워드 설정이다. Redis config 파일을 살펴보면 SECURITY 영역에 'requirepass'가 있다. 기본값은 주석처리되어 있지만 주석을 해제하고 우측에 인증 패스워드 값을 설정해준다.

 

 

두 번째는 binding 설정이다. 기본적으로 Redis 서버는 모든 네트워크와 연결 될 수 있다. 만약에 bind가 주석처리 되어 있다면 말이다. bind의 기본 값이 주석처리 되어 있지만 이를 해제하고 로컬(특정 IP)에서만 접속할 수 있도록 한다. 

 

 

세 번째는 Slave 읽기 전용 모드 설정이다. redis는 master-slave 구조를 갖는다. master에 붙는 slave는 read-only 권한만을 가져서 master의 자원에 write할 수 없어야 한다. 하지만 이는 이미 아래와 같이 기본 설정으로 되어 있을 것이다. 그대로 두면 된다. 

 

 

네 번째는 rename-command 설정이다. Redis에서는 보안 설정을 목적으로 rename-command를 제공한다. 이는 명령어를 다른 이름으로 치환하는 역할을 한다. 가령 예를 들어 CONFIG 명령을 사용하기 위해서는 b840fc로 시작하는 해시와 같은 예측할 수 없는 값으로 설정할 수 있다. 또는 CONFIG ""을 통해 아예 CONFIG 명령을 사용할 수 없도록 만들 수 있다.

 

 

보안 설정 미흡으로 시스템이 털리는 것은 사소한 판단에서도 기인할 수 있음을 느끼게 됐다. 앞으론 서버 보안 설정에 주의를 더 기울일 수 있도록 해야겠다. 다음에 Redis 서버 설치한다면 위 4가지 설정을 제일 먼저 하는 걸로. (그나저나 최근 이따금씩 PC나 다른 장치에서 들리는 비프음 같은 것은 뭘까 싶다.)

 

(PS: requirepass 주석해제 및 값 설정으로 패스워드 설정이 안된다면 redis-cli에서 "config set requirepass <password>" 명령어로 설정할 수 있음)

 

Reference

[1] KISA 클라우드 취약점 점검 가이드

 

문제 상황

Node JS 다루다 보면 자주 마주치는 오류라고 한다. property가 없어서 발생한다고 하지만 분명 값이 있었기에 당최 그 이유를 알 수 없었다. 내가 이 오류를 마주한 구문은 try catch이었다. try와 catch 각각의 return 구문이 있었고, 신기하게도 try에서도 return되고 catch에서도 return 되는 기이한 현상이었다. 또 이와 더불어 console.log에 값이 두 개씩 찍힌다는 것도 문제였다. 하나는 올바른 값이 들어 있지만 하나는 값 없이 undefined만 출력됐다. 어디가 문제인지, 무엇이 문제인지, 무엇을 모르는지 올바르게 떠올리지 못해 거의 하루를 낭비했다.

 

나의 경우는 HTML 쪽이 문제였다. 정확히는 form에서 submit이 실행될 때 이벤트를 듣고 있는 addEventListener 함수가 문제였다. 생각지도 못했다. 아래와 같이 addEventListener 함수를 한 번 호출했지만 계속해서 두 번씩 호출되고 있었고 이 때문에 console.log 값이 두 번씩 찍혔다.

"use strict";

const name = document.querySelector("#name"),
    email = document.querySelector("#email"),
    submitBtn = document.querySelector("#submit");

submitBtn.addEventListener("click", findUsername);

 

해결 방법

addEventListener 함수가 두 번씩 호출되고 console.log가 두 번씩 출력되는 이유는 아래와 같이 HTML의 form에서 onsubmit="return false;"이 빠져있다면 addEventListener가 두 번씩 호출되기 때문이다. 정확히는 onsubmit이 form에서 submit이 실행되면 발생하는 이벤트 핸들러로 기본값이 true로 되어 있기 때문에 addEventLitener와 중복되어 두 번씩 실행되는 것이다. 

<form class="login-form" action="/find-username" method="post">
    <h4>이름과 이메일을 입력해주세요.</h4>
    <input id="name" type="name" placeholder="이름"/>
    <input id="email" type="email" placeholder="이메일"/><br><br>
    <input type="submit" id="submit" value="확인">

따라서 위와 달리 onsubmit="return false;"를 추가해주면 더 이상 console.log에서 두 번 출력되지 않고 값도 undefined로 출력되지 않는다. 

<form class="login-form" action="/find-username" method="post" onsubmit="return false;">
    <h4>이름과 이메일을 입력해주세요.</h4>
    <input id="name" type="name" placeholder="이름"/>
    <input id="email" type="email" placeholder="이메일"/><br><br>
    <input type="submit" id="submit" value="확인">

 

음성인식 앱 개발에 흥미가 있던 터라 이끌려 사게 된 책이다. 내용은 음성인식의 과거, 현재, 미래를 이야기 하며 음성인식이 가져올 산업구조의 변화에 대해 이야기한다. 이를 위해 현재 구글, 아마존, 애플, 마이크로소프트와 같은 글로벌 IT 기업에서 음성인식 관련해 어떤 행보를 보이고 있고 어떤 패권다툼이 있는지 이야기 한다. 평소 음성인식 앱 개발에 있어 이렇게 해야할 것 같다, 저렇게 해야할 것 같다고 생각했던 것들이 여러 IT 기업들에서 동일하게 고민한 바 있어 바른 방향으로 생각했구나 하는 작은 희열감을 느꼈고, 차마 생각이 닿지 못했던 부분들에 대해 알 수 있어 좋았다. 

 

1부: 경쟁

- 음성은 만능 리모컨화 되고 있고, AI 스피커는 집안 내 모든 가전제품을 제어하는 '허브'역할을 할 것이다. 

- AI 스피커는 음성이란 특성상 사무실보다 가정에 적합할 것이다.

- 음성의 검색결과는 구글과 달리 하나만 보게 될 것이고, 그 결과 검색엔진 상단의 콘텐츠 노출 경쟁이 심화될 것이다.

- 음성은 구글의 수십억달러짜리 광고 비즈니스 모델을 위협한다. 

- 클라우드 덕분에 마이크와 와이파이 칩만 있으면 어떤 디바이스도 음성인식 장치가 될 수 있다.

- 회사들은 사활을 걸고 지배적인 새 OS를 개발하기 위해 고군분투 중이다.

- AI에게 페르소나 부여가 필요하다. 페르소나가 있는 AI 스피커의 앱 사용율이 더 높다. (by Google)

- AI는 수십년간 차세대 거대시장으로 기대받았지만 안정적 이윤창출을 성공한적이 없다.

- 구글은 1,700개 이상의 액션을 보유 중이다.

 

2부: 혁신

- 세계 최초 챗봇은 엘리자다. 1960년대 중반 MIT에서 만들어졌고 심리치료사 역할을 했다. 이후 1972년 심리치료챗봇 패리(Parry)가 스탠퍼드 대학 정신과 의사에 의해 만들어졌다. 

- 대화 중 이어지는 다음 말이 올 수 있는 순열은 무한하다. 예상대로 대화를 흘러가도록 만들 수 없다. 

- 한 가지 주제에 집중한 챗봇은 그나마 만들 수 있다.

- 수학자 조지 불 이름을 딴 게 불(Bool) 논리다. 측량사 조지에베레스트 이름 딴 산이 에베레스트 산이다.

- 친밀감과 효율성은 Trade-off 적 성격을 띤다. 개인적 따듯함과 직업적 냉정함 사이의 균형이 필요하다.

- 구글의 AI 스피커 설계에 있어 핵심 원칙 중 하나는 사람처럼 말하되, 사람인 체 하지 않는 것이다.

- 희곡에선 강한 견해가 캐릭터를 흥미롭게 하는 요인이지만 AI 스피커 설계에 있어선 양극화를 일으키지 않을 정도의 성격을 만들어야 한다.

- 사용자들은 각각 고유한 AI 비서를 찾고 있다. 따라서 사용자 범주별 맞춤형 성격을 만들필요가 있다. 

- 각자 전문성을 갖춘 작은 모델로 나눠 앙상블을 구성했을 때 더 좋은 평점을 받았다. 

 

3부: 혁명

- 구글이 찾아주는 100만 개 링크는 시리의 정확한 답변 하나보다 훨씬 가치가 낮다.

- 원샷 답변이란 단 하나의 정확한 답변을 제공하는 것이다.

- 웹캠과 동작추적센서로 표정분석할 수 있다. 또 말 속도, 길이, 어조 분석을 통해 현재 상태에 대한 단서가 될 수 있다. 

- 자제력과 같은 것은 프로그래밍이 쉽지 않다. 또 시간 구분 감각에 대한 프로그래밍이 필요하다.

- 훌륭한 사람은 물론 강한신체와 운동능력을 겸비해야겠지만 고귀한 정신, 부드러운 마음, 고상한 영혼은 수 많은 미덕의 출발점이다.

- 거대 기술 기업이 어디로 향할지 미리 알아 보는 좋은 방법은, 그들의 특허 신청 서류를 검토해보면 된다.

논문 제목: Multi-Task Pre-Training for Plug-and-PlayTask-Oriented Dialogue System

게재 학회 / 게재 년도: ACL / 2022.05

 

이 논문은 기존의 모듈화된 dialogue system을 하나의 모델에서 end-to-end 방식으로 동작가능한 PPTOD라는 모델에 관한 논문이다. 기존의 dialogue system은 대개 4개의 모듈인 NLU, DST, DP, NLG로 나뉜 방식으로 구성된다. 논문에서는 이러한 모듈화된 방식에 순서성이 있다고 하여 cascaded 방식이라 부른다. 하지만 이 방식에는 크게 3가지 문제가 있다고 말하며 PPTOD 모델의 연구 배경을 말한다. 그 문제는 모듈화된 계단식 dialogue system 구성이 첫 번째로 이전 모듈에서 에러가 발생하면 이후 모듈에 에러가 전파된다는 것이며 두 번째로 모든 모듈에서 각 모델이 학습하기 위해 각각의 데이터셋 수집과 라벨링 과정이 필요하고 마지막으로 계단식이기에 필연적으로 Inference latency가 느려진다는 것이다.

따라서 이러한 문제점을 해결하기 위해 end-to-end 방식의 PPTOD라는 모델을 제시한다. 여기서 end-to-end란 기존의 NLU, DST, DP, NLG를 하나로 통합한 것이다. 따라서 유저의 utterance가 들어오면 한번에 1. 의도 분류 2. 슬롯 필링 3. 액션 생성 4. 대답 생성이 가능하다. 아래 PPTOD 모델을 만들기 위해 pre-training하는 예시를 살펴보자.

가장 앞에 "translate dialogue to A"는 하나의 모델에서 DST, NLU, DP, NLG 중 어떤 것인지 구분하기 위해 사용되는 일종의 prefix이다. 이 prefix는 위 그림과 같이 "belief state", "user intent", "dialogue act", "system response"가 있다. 두 번째로 DST를 위해 이전까지 유저와 봇이 주고 받은 대화와 현재 유저의 utterance를 모두 concatenation해준 다음 입력으로 넣어준다. 그렇게 되면 이제 prefix에 따라 생성되는 결과값이 4가지로 분리된다. 즉, slot filling된 결과, user intent, bot action, bot 응답이다. 간단히 정리하면 prefix와 유저 utterance가 입력으로 들어가고 4개의 결과를 모두 출력할 수 있는 구조인 것이다. 다르게 말하면 세부적으로 모듈화된 task-oriented dialogue 문제를 단일한 포맷의 text generation 문제로 바꾼 모델이다. 

이 T5 기반의 end-to-end 모델을 학습하기 위해 추가적인 pre-training과, fine-tuning 과정을 거쳤다. 데이터셋은 기존의 Dialogue System을 만들기 위해 공개된 아래 데이터셋을 조합했다.

총 80개 도메인의 230M개 가량의 유저 utterance 데이터셋을 사용했다. 우선 pre-training을 위해 사용한 세부적인 하이퍼파라미터는 learning rate: 5e-5, epoch: 10, optimizer: Adam, model: T5, max_seq_len: 1024, batch_size: 128, loss: maximum likelihood이며 구현의 용이성을 위해 허깅페이스 라이브러리를 사용했다. fine-tuning은 pre-training과 동일한 하이퍼 파라미터를 사용했다.

 

모델 학습에 사용하는 데이터셋의 형태는 $d = (z_t, x, y)$을 가진다. $d$는 데이터셋을 의미하고, $\displaystyle t \in \{NLU, DST, DP, NLG\}$이고 $z_t$는 "translate dialogue to A:" 형태의 prompt를 의미한다. $x$는 유저의 현재 발화 + 이전의 유저 발화 + 봇 응답이 전부 concatenation 된 형태이다. $y$는 생성해야할 target sequence를 의미한다. 학습에 사용한 loss 함수는 maximum likelihood를 사용했다. 

 

PPTOD 모델의 버전은 크게 3가지로 small, base, large 모델이 있다. 각각 t5-small, t5-base, t5-large에 대해 pre-training하고 fine-tuning한 결과이다. 다만 학습시킬 때 각각의 사이즈 별로 다른 configuration을 사용했다고 한다. 이에 대한 별도의 언급은 없다. t5 모델의 기본 configuration을 사용했을 것이다. 

 

PPTOD 모델을 평가하기 위해 크게 3가지 측면에서 벤치마킹을 수행했다. 1. end-to-end dialogue modeling 2. DST 3. user intent classification 측면이다. 벤치마킹을 위해 MultiWOZ 2.0과 MultiWOZ 2.1를 사용했다. 결과적으로 3가지 측면 모두 PPTOD 모델의 우수성을 이야기하고 있다. 

 

 

첨언하자면 MultiWOZ 데이터셋에 있는 Inform, Success, BLeU, Combined Score는 MultiWOZ 데이터셋에서 제시하는 평가 가이드라인이라고 한다. 또 Combined Score는 (Inform + Success) * 0.5 + BLUE로 계산된다고 한다. 위 표의 성능을 보면 PPTOD base 모델이 가장 좋다. PPTOD large 모델이 오히려 성능이 떨어지는 것은 사전 훈련 단계에서 보지 못했던 어휘에 대해 토큰을 생성하는 방법 학습할 때 능력이 떨어지는 것으로 분석한다고 말한다. 이 말이 잘 와닿진 않지만 일단은 PPTOD base 모델이 가장 좋다고 한다. 

 

이 논문의 저자들은 또 PPTOD 모델이 적은 데이터셋에서도 좋은 성능이 나는지 보기 위해서 학습 데이터셋을 1% 썼을 때, 5% 썼을 때, 10% 썼을 때, 20% 썼을 때에 대해 모델 성능을 비교했다. 참고로 표를 만들기 위해 5회 모델 학습에 대한 평균성능을 기재했다. 

1% 학습 데이터셋만으로도 다른 모델들보다 성능이 뛰어남을 보인다. 여기까지가 1. end-to-end dialogue modeling에 대한 벤치마크 평가다. 이외의 2. DST 측면의 평가와 3. user intent classification 측면의 평가도 모두 PPTOD large 모델이 우수하다는 것을 말하므로 생략한다. 

 

마지막으로 Inference latency 측면에서 PPTOD 모델(plug-and-play)이 기존의 cascaded 방식의 모델들보다 비약적으로 빨라졌다. 

 

200ms도 느리진 않지만 서비스 측면에서는 14배 빠른 end-to-end (plug-and-play) 모델이 경쟁력을 보일 수 있을 것이다. 

 

끝으로 이 논문의 핵심 컨트리뷰션은 기존의 챗봇이 NLU, DST, DP, NLG와 같이 모듈화되어 있었다면 이 모듈화된 것을 end-to-end 방식으로 바꿨다는 데 있다. 또 이를 통합함으로써 자연스럽게 모델 추론 속도가 향상되었다는 점이다. end-to-end 모델의 우수성은 이 논문의 PPTOD 모델로 증명되었다. 다만 TOD 챗봇을 위해 다양한 도메인의 데이터셋이 만들어진다면 앞으로 많은 end-to-end 연구가 이루어질 수 있을 것이라 생각한다.

+ Recent posts