본문 바로가기
서버, 인프라

리눅스 TCP 취약점 CVE-2026-98432, 패치 없는 Ubuntu 서버에서 먼저 한 일

by 요즘IT 2026. 11. 2.

23개. 제 Hetzner 서버 한 대에서 지금 돌고 있는 도커 컨테이너 수예요. 직접 운영하는 웹 서비스 여러 개와 DB, Jenkins까지 전부 이 한 대 위에 있어요.

php 보안 취약점에 이어서 내껀 아니다 안심했는데 리눅스 보안 취약점이라니.. 힘들지만 또 찾아보며 조치해야되겠죠?!

이번 리눅스 커널 TCP 취약점 CVE-2026-98432는 한 줄로 이래요. 로그인 없이, 앱이 연결을 받기도 전에, 커널 안에서 터지는 버그. CVSS 9.8이에요. 문제는 제 서버가 Ubuntu라는 거예요. Ubuntu는 아직 고친 커널을 내지 않았거든요. 그래서 패치가 나오기 전까지 제가 먼저 한 일을 순서대로 적어 둡니다.

경비실에 난 구멍이라 앱 설정으로는 못 막아요

아파트 현관을 떠올리면 쉬워요. 손님(패킷)이 오면 경비실(커널)이 먼저 확인하고, 그다음 집(앱)으로 올려 보내죠.

이번 구멍은 경비실 안에 있어요. 손님이 초인종을 누르기도 전, 경비실에서 방문증을 처리하는 단계에서 문제가 생겨요. 집 안에서 nginx 설정이나 스프링 시큐리티로 문을 아무리 잘 잠가도 소용이 없는 이유예요.

도커 컨테이너는 같은 건물의 방들이에요. 방이 23개여도 경비실은 하나죠. 컨테이너는 호스트 커널을 같이 쓰니까요. 도커 이미지를 새로 빌드해도 경비실은 그대로라는 뜻이에요.

기술적으로는 IPv4 TCP 핸드셰이크 중에 IP 옵션 데이터를, 이미 해제한 메모리에서 다시 읽는 use-after-free 버그예요. 수정 커밋은 kfree() 두 곳을 kfree_rcu()로 바꾼 거고요.

도커 컨테이너 23개가 리눅스 커널 하나를 공유하는 구조와 CVE-2026-98432 취약 지점
도커 컨테이너 23개가 리눅스 커널 하나를 공유하는 구조와 CVE-2026-98432 취약 지점

원문 요약: 영향 범위와 배포판 상태

자료는 세 곳을 직접 열어 확인했어요.

리눅스 4.4부터 영향이 있고, 업스트림에서는 아래 버전에서 고쳐졌어요.

커널 계열 고친 버전

5.10 5.10.272
5.15 5.15.223
6.1 6.1.190
6.6 6.6.159
6.12 6.12.113
6.18 6.18.56
7.2 7.2.10
7.3 7.3

배포판 상태는 Atlas 10/31 기준으로 이래요. Debian 12·13, Amazon Linux 2·2023, Oracle UEK는 고친 커널이 나왔어요. RHEL 8·9·10은 "영향 있음, 수정 없음"이에요. Ubuntu는 전 릴리스가 Vulnerable이고, 22.04 이상은 "work in progress"로 수정 버전 번호만 잡혀 있어요.

보고자는 Anthropic 연구자예요. Anthropic은 Claude가 MPTCP(Multipath TCP, 연결 하나를 여러 경로로 나눠 보내는 TCP 확장) 리스너가 있는 서버에서 root 명령 실행까지 가는 익스플로잇을 만들었다고 밝혔어요. 코드는 공개하지 않았고요. Go 1.24 이상으로 만든 프로그램은 리눅스에서 기본으로 MPTCP 리스너를 열어요. 다만 Go 보안팀은 "버그 자체는 MPTCP 전용이 아니다"라고 했어요.

① 커널 버전 확인: 업데이트가 떠 있다고 고쳐진 게 아니에요

# dpkg -l 'linux-image*' | grep ^ii
ii  linux-image-7.0.0-34-generic   7.0.0-34.34  amd64  Signed kernel image generic
ii  linux-image-7.0.0-38-generic   7.0.0-38.38  amd64  Signed kernel image generic
ii  linux-image-virtual            7.0.0-38.38  amd64  Virtual Linux kernel image

# apt list --upgradable 2>/dev/null | grep -i linux-image
linux-image-virtual/resolute-updates 7.0.0-42.42 amd64 [upgradable from: 7.0.0-38.38]

Ubuntu 26.04 LTS(resolute), 7.0 커널 계열이에요. 설치된 커널은 7.0.0-34와 7.0.0-38 두 개고요.

그럼 지금 돌고 있는 건 어느 쪽일까요?

# uname -r
7.0.0-34-generic

34예요. 38이 깔려 있는데 재부팅을 안 해서 아직 예전 커널로 돌고 있었던 거예요. 설치만 하고 재부팅을 안 하면 커널은 안 바뀌어요. 이번 CVE 패치가 나와도 똑같아요. 받아 놓기만 하면 서버는 계속 구멍 난 커널로 돌아요. 제 서버가 지금 그 상태였고요.

하나 더 걸려요. 업그레이드 가능한 버전으로 7.0.0-42.42가 떠 있어요. "업데이트 있네? 올리고 재부팅하면 끝?" 싶잖아요. 근데 Ubuntu 트래커에서 26.04 수정은 7.0.0-43.43에 "work in progress"로 잡혀 있어요. 42.42의 changelog에서 CVE 번호를 찾아봤어요.

# apt changelog linux-image-7.0.0-42-generic | grep -i 98432

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

경고 한 줄 말고는 아무것도 안 나와요. 42.42 changelog에는 CVE-2026-98432가 없어요. 지금 올라와 있는 업데이트를 받아도 이번 구멍은 그대로라는 얘기예요.

② 열린 포트 정리: 문이 몇 개 열려 있나

# ss -tlnp   (IPv4 외부 포트만 발췌)
LISTEN 0 4096  0.0.0.0:8090   0.0.0.0:*  users:(("docker-proxy",...))
LISTEN 0 4096  0.0.0.0:50000  0.0.0.0:*  users:(("docker-proxy",...))
LISTEN 0 4096  0.0.0.0:5003   0.0.0.0:*  users:(("docker-proxy",...))
LISTEN 0 4096  0.0.0.0:80     0.0.0.0:*  users:(("docker-proxy",...))
LISTEN 0 4096  0.0.0.0:22     0.0.0.0:*  users:(("sshd",...))
LISTEN 0 4096  0.0.0.0:443    0.0.0.0:*  users:(("docker-proxy",...))

외부(0.0.0.0)에 열린 IPv4 TCP 포트는 6개예요. 22, 80, 443, 5003, 8090, 50000. 이번 버그는 IPv4 TCP 포트가 열려 있기만 하면 건드릴 수 있어요. 경비실 출입구가 6개라는 얘기죠.

80, 443, 22는 닫을 수 없어요. 서비스가 멈추니까요. 남은 건 5003, 8090, 50000이에요. 어느 컨테이너가 열었는지 봤어요.

# docker ps --format '{{.Names}}\t{{.Ports}}'   (외부 포트가 있는 것만 발췌)
app-b-web 0.0.0.0:5003->3000/tcp
nginx           0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp
jenkins         0.0.0.0:50000->50000/tcp, [::]:50000->50000/tcp, 0.0.0.0:8090->8080/tcp, [::]:8090->8080/tcp

23개 중에 외부 포트를 직접 연 건 셋뿐이에요. 나머지 20개는 내부 포트만 쓰고 nginx 뒤에 숨어 있어요.

눈에 걸리는 건 Jenkins예요. 8090은 Jenkins 웹 화면(컨테이너 8080), 50000은 에이전트 접속 포트예요. ss와 docker ps만 보면 둘 다 0.0.0.0, 그러니까 인터넷 전체에 열린 것처럼 보여요.

채굴 악성코드 사건(서버가 털린 날) 이후에 Jenkins 접근 방식을 바꿔 뒀어요. Jenkins용 도메인은 DNS에서 빼고, nginx에서는 그 도메인으로 오는 요청을 아무 응답 없이 끊게(return 444) 했어요. 그리고 Hetzner Cloud Firewall에 규칙을 만들었어요. 22와 8090은 제 IP만, 80과 443은 전체 허용. 그 외 포트는 전부 막히는 구조예요.

그래서 8090은 제 IP만 들어온다고 생각하고 있었어요. 서버 안을 먼저 확인했어요.

# ufw status verbose
Status: inactive

# iptables -L DOCKER-USER -n -v
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination

서버 안에는 막는 규칙이 하나도 없어요. 그럼 Hetzner 방화벽이 다 막고 있어야 하죠. 콘솔을 열어 봤어요.

규칙은 다 맞게 들어가 있었어요. 그런데 방화벽 이름 옆에 Not applied, 그 아래 Applied to 0 Resources. 규칙만 만들고 서버에 붙어 있지 않았던 거예요. 22, 8090, 50000, 5003 전부 인터넷 전체에 열려 있었다는 뜻이에요.

다 만들어놓고 적용을 안했다니.. 여러분은 꼭 다시한번 확인하셨으면 좋겠어요..

확인한 그날 바로 Resources 탭에서 서버에 적용했어요. 상태가 Fully applied, Applied to 1 Resource로 바뀌었어요.

Hetzner Cloud Firewall 적용 전 Not applied 상태와 적용 후 Fully applied 상태
Hetzner Cloud Firewall 적용 전 Not applied 상태와 적용 후 Fully applied 상태

같은 걸 하실 분은 적용 전에 하나만 확인하세요. 허용 목록에 지금 접속 중인 내 IP가 있는지요. 22번을 특정 IP만 열어 둔 규칙이라면, 목록에 없을 때 적용하는 순간 SSH가 끊겨요. 휴대폰 핫스팟이나 LTE 라우터의 IP는 통신사 가입자들이 같이 쓰는 주소라 허용 목록에 넣지 않는 게 좋고요.

5003과 50000은 규칙에 아예 없어요. Hetzner 방화벽은 규칙에 없는 인바운드를 전부 막으니까, 적용한 뒤로는 이 두 포트도 밖에서는 닿지 않아요. 컨테이너가 0.0.0.0으로 열어 둔 건 그대로인데도요.

이제 휴대폰에서 접근 해보시면 접근 안되실꺼예요!

여기서 배운 게 두 가지예요. 첫째, ss -tlnp의 0.0.0.0은 "이 포트에서 듣고 있다"는 뜻이지, "누구나 들어올 수 있다"는 뜻이 아니에요. 실제로 열려 있는지는 그 앞단 방화벽까지 봐야 해요. 둘째, 방화벽은 규칙이 아니라 "적용 대상"까지 확인해야 해요. 규칙 화면만 보면 완벽해 보이거든요. 다른 IP에서 직접 접속해 보는 게 제일 확실해요.

Jenkins를 밖에 열어 두면 안 되는 이유는 예전 글(왜 CI 서버(젠킨스)는 외부에 노출하면 안 될까)에 썼어요. 방화벽을 적용한 지금에서야 그 글의 결론대로 된 셈이에요.

덤으로 나온 것: 7주 전에 만료된 인증서

nginx 설정을 보다가 하나 더 걸렸어요. Jenkins용 서브도메인 인증서예요.

# openssl x509 -enddate -noout -in .../live/<jenkins 서브도메인>/fullchain.pem
notAfter=Sep 15 17:59:31 2026 GMT

9월 15일에 만료됐어요. 수동으로 갱신을 돌려 보니 이유가 바로 나왔어요.

Detail: DNS problem: NXDOMAIN looking up A for <jenkins 서브도메인>
...
1 renew failure(s), 0 parse failure(s)

채굴 사건 뒤에 이 도메인을 DNS에서 뺐으니 갱신이 될 리가 없죠. 문제는 그걸 아무도 몰랐다는 거예요. 갱신 cron이 이렇게 돌고 있었거든요.

17 4 * * 1 docker run --rm ... certbot/certbot renew --quiet ; docker exec nginx nginx -s reload

--quiet라서 실패해도 아무 흔적이 안 남아요. 매주 월요일 새벽마다 실패하고 있었을 텐데요. 쓰지 않는 도메인이라 피해는 없었지만, 쓰는 도메인이었다면 예전에 겪은 SSL 만료를 그대로 한 번 더 겪었을 거예요.

참고로 같은 포트가 IPv6([::])에도 열려 있어요. 수정 커밋 설명에는 "IPv6는 첫 번째 문제의 영향을 받지 않는다"고 되어 있어요. 관련된 IPv6 쪽 경우는 별도 패치로 처리한다고 하고요.

③ MPTCP 확인: 호스트만 보면 속아요

# ss -Mlnp
State  Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process

# sysctl net.mptcp.enabled
net.mptcp.enabled = 1

호스트에는 MPTCP 리스너가 하나도 없어요. 여기서 "익스플로잇 조건은 피했네" 하고 넘어가기 쉬워요.

근데 여기서 반전이 있어요. MPTCP 설정은 네트워크 네임스페이스마다 따로예요. 새로 만든 네임스페이스는 켜진 상태로 시작하고요(Atlas). 컨테이너마다 값을 찍어 봤어요.

# for c in $(docker ps -q); do echo "$(docker inspect -f '{{.Name}}' $c): $(docker exec $c cat /proc/sys/net/mptcp/enabled 2>/dev/null)"; done
/app-a-web: 1
/app-a-api: 1
/app-b-web: 1
/app-b-api: 1
/app-c-web: 1
/app-c-api: 1
(중략)
/app-d-db: 1
/app-c-db: 1

23개 전부 1이에요. 하나도 꺼진 게 없어요. 그리고 호스트에서 돌린 ss -Mlnp는 호스트 네임스페이스의 소켓만 보여줘요. 컨테이너 안에서 열린 리스너는 저 목록에 안 나와요. 호스트 결과가 비어 있다고 안심하면 안 되는 이유예요.

컨테이너 안까지 보려면 네임스페이스에 들어가서 봐야 해요.

for c in $(docker ps --format '{{.Names}}'); do
  pid=$(docker inspect -f '{{.State.Pid}}' "$c")
  echo "== $c"; nsenter -t "$pid" -n ss -Mlnp
done

제 백엔드는 대부분 Java(Spring Boot)예요. Go로 만든 앱이 아니니까 MPTCP 리스너는 없을 거라고 보기 쉽죠. 결과는 달랐어요.

== app-a-web
State   Recv-Q  Send-Q  Local Address:Port   Peer Address:Port  Process
LISTEN  0       4096    127.0.0.11:45311     0.0.0.0:*          users:(("dockerd",pid=1203,fd=138))
== app-d-api
LISTEN  0       4096    127.0.0.11:44249     0.0.0.0:*          users:(("dockerd",pid=1203,fd=259))
== jenkins
LISTEN  0       4096    127.0.0.11:42187     0.0.0.0:*          users:(("dockerd",pid=1203,fd=207))
(중략)
== buildx_buildkit_default
State   Recv-Q  Send-Q  Local Address:Port   Peer Address:Port  Process

23개 중 22개 컨테이너에 MPTCP 리스너가 하나씩 있어요. 리스너를 연 건 제 앱이 아니라 dockerd, 그러니까 도커 데몬이에요. 주소는 전부 127.0.0.11이에요. 도커가 사용자 정의 네트워크의 컨테이너마다 넣어 주는 내장 DNS 주소죠. 포트는 컨테이너마다 제각각이고요. 빠진 하나는 buildx_buildkit_default예요.

도커 데몬은 Go로 만든 프로그램이에요. 어떤 Go로 빌드됐는지 봤어요.

# docker version --format '{{.Server.Version}} / {{.Server.GoVersion}}'
29.5.3 / go1.26.4

Docker 29.5.3, Go 1.26.4예요. Go 1.24 이상으로 만든 프로그램은 리눅스에서 리스너를 기본으로 MPTCP로 열어요. 그게 내장 DNS의 TCP 리스너에 그대로 적용된 걸로 보여요. "보여요"라고 쓴 이유가 있어요. Go의 이 기본값은 빌드에 쓴 Go 버전이 아니라 소스의 go.mod에 적힌 go 버전을 따라가요(Atlas). 그래서 빌드 버전만으로는 단정할 수 없어요. 다만 ss -M에 MPTCP 리스너로 찍혀 나온 건 추정이 아니라 실제 출력이에요.

그럼 얼마나 위험할까요? 정리해 보면 이래요.

  • 주소가 127.0.0.11이라 인터넷에서 바로 닿지는 않아요. 그 컨테이너 안에서만 접속할 수 있는 주소예요.
  • 대신 컨테이너 하나가 먼저 뚫리면 얘기가 달라져요. 안에 들어온 공격자는 바로 옆의 MPTCP 리스너를 건드릴 수 있어요. 커널은 호스트 하나를 같이 쓰니까, 성공하면 컨테이너 밖 호스트 root까지 갈 수 있는 길이 돼요.
  • 루프백에 열린 리스너로도 Anthropic이 말한 익스플로잇 조건이 되는지는 확인하지 못했어요. Anthropic도 MPTCP 리스너가 왜 필요한지는 밝히지 않았어요(Atlas). [확인 필요]

이 리스너는 "컨테이너 하나가 뚫린 다음" 단계를 열어 주는 셈이에요.

끄는 방법은 두 겹이에요. 호스트는 sysctl 파일로, 컨테이너는 compose에 sysctls로요.

# 호스트
echo 'net.mptcp.enabled = 0' | sudo tee /etc/sysctl.d/90-disable-mptcp.conf
sudo sysctl -w net.mptcp.enabled=0

# docker-compose.yml (컨테이너마다)
services:
  app-d-api:
    sysctls:
      - net.mptcp.enabled=0

이미 열린 리스너는 MPTCP 상태로 남아요. 설정을 바꾼 뒤 서비스를 재시작해야 해요.

제 경우는 리스너를 연 게 도커 데몬이라 한 가지 방법이 더 있어요. Go 보안팀이 안내한 GODEBUG=multipathtcp=0을 dockerd에 주는 거예요.

sudo systemctl edit docker
# 아래 두 줄 추가
[Service]
Environment="GODEBUG=multipathtcp=0"

sudo systemctl restart docker

다만 Go 보안팀은 이 방법을 "깨지기 쉬운 완화책"이라고 했어요. 코드가 MPTCP를 직접 켜면(SetMultipathTCP) 이 설정이 무시되거든요. 그리고 도커를 재시작하면 컨테이너 23개가 같이 내려갔다 올라와요. 혼자 운영하는 서버에서는 이것도 작은 장애예요.

어느 방법이든 적용한 뒤에는 위의 nsenter 반복문을 다시 돌려서 127.0.0.11 리스너가 MPTCP 목록에서 사라졌는지 봐야 해요.

④ nftables 임시 차단 규칙

이 글을 쓰는 시점에는 아직 규칙이 없어요.

# nft list table ip cve_2026_98432
Error: No such file or directory

Atlas가 제시한 규칙은 이거예요.

nft add table ip cve_2026_98432
nft add chain ip cve_2026_98432 pre '{ type filter hook prerouting priority -300; }'
nft add rule ip cve_2026_98432 pre meta l4proto tcp ip hdrlength gt 5 counter drop

# 되돌리기
nft delete table ip cve_2026_98432

ip hdrlength gt 5가 핵심이에요. IPv4 헤더 길이는 4바이트 단위로 적히는데, 기본 헤더는 5(20바이트)예요. 5보다 크면 IP 옵션이 붙었다는 뜻이고, 그런 TCP 패킷은 버리는 거예요. 평범한 웹 트래픽에는 IP 옵션이 거의 붙지 않아요.

prerouting priority -300은 도커의 NAT 처리(-100)보다 먼저 패킷을 본다는 뜻이에요. 그래서 컨테이너로 넘어가는 패킷까지 걸러져요. Atlas 테스트에서도 컨테이너로 라우팅되는 패킷은 걸렸다고 해요.

주의할 게 하나 있어요. 이 규칙은 재부팅하면 사라져요. 그렇다고 Ubuntu 기본 /etc/nftables.conf에 넣고 nftables 서비스를 켜면 안 돼요. 그 파일 첫 줄이 flush ruleset이라, 도커가 만든 규칙까지 같이 지워버리거든요. 별도 파일로 두고 nft -f로만 불러오는 게 안전해요.

⑤ 서비스 영향: 규칙 넣기 전 기준부터 쟀어요

규칙을 넣기 전에 제 서비스 하나의 응답시간을 먼저 쟀어요. 서버 안에서 메인 페이지를 10번 호출했어요.

# for i in $(seq 10); do curl -o /dev/null -s -w '%{time_total}\n' https://<서비스 도메인>/; done
0.079287
0.674055
0.068354
0.683275
0.070679
0.073208
0.071443
0.696307
0.070161
0.078578

nftables 규칙 적용 전 응답시간 10회 측정 그래프
nftables 규칙 적용 전 응답시간 10회 측정 그래프

10번 중 7번은 0.068~0.079초, 평균 약 73ms예요. 눈 한 번 깜빡이는 게 150ms 정도니까 그 절반이죠. 나머지 3번은 0.674~0.696초였어요. 열 배 가까이 느려요. 중앙값은 0.076초고요.

이게 포인트예요. 규칙을 넣기 전부터 10번 중 3번은 이미 느렸어요. 기준을 안 재고 규칙부터 넣었으면 "nftables 때문에 느려졌다"고 착각했을 거예요. 느린 3번의 원인은 아직 확인 못 했어요.

⑥ 패치 후 재부팅: 패치 대기 중

Ubuntu 26.04용 수정 커널(트래커상 7.0.0-43.43)이 나오면 이 순서로 할 계획이에요.

apt update && apt upgrade
reboot
uname -r
docker inspect -f '{{.Name}} {{.HostConfig.RestartPolicy.Name}}' $(docker ps -aq)

마지막 줄은 컨테이너 재시작 정책 확인용이에요. 23개가 재부팅 후에 다 알아서 살아나는지 봐야 하니까요.

①에서 봤듯이 지금도 38을 깔아 놓고 34로 돌고 있어요. 이번엔 받아 놓고 재부팅을 미루면 안 돼요.

임시 규칙의 한계와 솔직한 생각

이 규칙은 커널을 고치지 않아요. Atlas도 실제 익스플로잇으로 시험한 건 아니라고 밝혔어요. Red Hat은 자기들이 낸 규칙(input 훅)에 대해 "노출을 줄이지만 완전히 막지는 못한다"고 했고요. AlmaLinux는 "같은 호스트의 컨테이너끼리 주고받는 트래픽은 규칙을 비켜갈 수 있다"고 했어요. Atlas 테스트에서도 브리지로 바로 오가는 패킷은 규칙에 한 번도 잡히지 않았다고 해요.

③에서 본 127.0.0.11 리스너도 이 규칙으로는 못 막아요. 규칙은 호스트 네트워크 네임스페이스에 들어가는데, 컨테이너 안 루프백 트래픽은 컨테이너 자기 네임스페이스 안에서만 오가거든요. 네임스페이스가 다르면 방화벽 규칙도 따로예요.

컨테이너 23개가 한 호스트에 있는 제 구조에서는 이 부분이 제일 신경 쓰여요. 컨테이너 하나가 뚫리면 옆 방으로 가는 길은 이 규칙이 못 막을 수 있다는 얘기니까요. MPTCP를 꺼도 Go 보안팀 말처럼 MPTCP 없는 경로가 있을 수 있고요.

그래서 이 규칙은 자물쇠가 아니라 시간 벌기용이에요. 방화벽으로 열린 포트 줄이기, MPTCP 끄기, 임시 규칙까지 세 겹을 쌓고 패치를 기다리는 거예요.

이번 점검에서 가장 급했던 건 CVE 대응 자체보다 서버에 안 붙어 있던 방화벽이었어요. CVE 때문에 포트를 하나씩 확인하지 않았다면 Jenkins와 SSH가 인터넷 전체에 열린 상태는 그대로였을 거예요.

정리: 이미지가 아니라 호스트 커널을 고쳐야 해요

CVE-2026-98432는 컨테이너 이미지가 아니라 호스트 커널을 고쳐야 하고, 그 전까지는 포트와 임시 규칙으로 버티는 수밖에 없어요.

도커 서버를 운영 중이라면 바로 해볼 수 있는 건 네 가지예요.

  1. uname -r과 apt list --upgradable을 Ubuntu 트래커의 수정 버전 번호와 비교하기
  2. 클라우드 방화벽은 규칙이 아니라 "적용 대상"까지 확인하고, 다른 IP에서 직접 접속해 보기
  3. 호스트가 아니라 컨테이너마다 net.mptcp.enabled 값 확인하기
  4. 방화벽 규칙을 넣기 전에 응답시간 기준부터 재기

저는 Ubuntu 패치가 나오면 재부팅 결과를 이 글에 보강하고, 자동 보안 업데이트(unattended-upgrades)를 켤지도 따져볼 생각이에요.