それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

UDPにコネクション・ステートはあるのか?

UDP にコネクションはあるのか

UDPはステートレスと、教科書では習うが。実際にはUDPはステートがある。

conntack で見てもわかるのですが。ss でパケットがESTABLISHEDになってたりする。

実験環境

最初に実験環境を整理しておく

ネットワーク構成を作る。

実際の構成は次の通り。

準備

lxc と netns で実験環境を作る。

## コンテナ作成
lxc launch ubuntu:22.04 t01
lxc config set t01 security.nesting true
lxc restart t01
lxc shell t01
## ncat インストール
echo 'Acquire::HTTP::Proxy "http://apt-cacher.lan";' | tee  /etc/apt/apt.conf.d/01proxy
apt update && apt upgrade -y
apt install ncat

## デバイス追加
ip link add name veth0 type veth peer name veth0-c01
ip netns add c01
ip link set veth0-c01 netns c01
ip netns exec c01 ip link set veth0-c01 name eth0
ip link set veth0 name eth1

## アドレス追加
ip netns exec c01 ip addr add 10.2.0.2/24 dev eth0
ip addr add 10.2.0.1/24 dev eth1

## リンクアップ
ip netns exec c01 ip link set eth0 up
ip link set eth1 up

## ルーティング
ip netns exec c01 ip route add default via 10.2.0.1 dev eth0

疎通確認する。

lxc shell t01
ncat -ul 10.2.0.1 80

もう一つ別の端末で、ncatへ接続する

lxc shell t01
ip netns exec c01 ncat -u 10.2.0.1 80

双方で文字列を送信できて通信できたらOK

REJECT する。

通信拒否を入れてあげて、パケットが拒否されることを確認

iptables -A OUTPUT -p udp --sport 80 -d 10.2.0.2 -j REJECT

ESTABLISHED(通信確立)は許可する。

iptables -A OUTPUT -p udp --sport 80 -d 10.2.0.2 -j REJECT
iptables -I OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT

ESTABLISHEDを許可すると、応答できることがわかる。

ここから「コネクション確立」という<状態>がUDPにあるとわかる。

UDPにESTABLISHEDはある。

この実験で分かる通り、ESTABLISHEDでチェックしている。

UDPは 宛先IP/ポートで区別していて、送信先を記憶している。なので接続の確立はわかる。

具体的な話を考えるときりがないけど、UDPはSRC/DSTをチェックして接続を見ていると思っておくといい。IPレベルでコネクションがあり、完全なステートレスというわけでもない。UDPはステートレスでいくらでも送れるが、応答パケットはIP/ポートで識別している。

その他の確認方法

ncat -lu 0.0.0.0で接続待ちを作って、他のIPから接続すると接続できない。なので動きがよく分かる。

まとめ

UDPは規格はステートレスではあるが、実際のLinux実装では、ある程度ステートがある。

送信元で識別して接続状態を作ってる。(パケットに応答するため、どこから繋がったかを管理している、つまり状態がある)ということになるのかな。

参考資料

https://serverfault.com/questions/123208/iptables-p-udp-state-established