NATの種類
Mappingの種類
マッピングはNAT内部から外部にパケットを送信時にアドレス変換する行為です。
- Endpoint-Independent Mapping
NAT内部のネットワークの同じIPアドレスとポートで外部のそれぞれのUDPサーバ(IPアドレスとポートが違う)にパケットを送信すると、各個UDPサーバも同じIPアドレスとポートのパケットを受信する。
例えば:
| 送信元アドレス | 宛先アドレス | NATマッピングアドレス |
|---|---|---|
| 192.168.1.1:3000 | 1.1.1.1:3000 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.1:3001 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.3:3002 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.4:3004 | 43.124.222.234:4500 |
- Address-Dependent Mapping
UDPサーバのアドレスが同じ(ポートが違う)なら受信したパケットのIPアドレスとポートを変換しない、そうしないと、IPアドレスやポートを変換する。
例えば:
| 送信元アドレス | 宛先アドレス | NATマッピングアドレス |
|---|---|---|
| 192.168.1.1:3000 | 1.1.1.1:3000 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.1:3001 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.2:3000 | 43.124.222.234:4501 |
| 192.168.1.1:3000 | 1.1.1.3:3003 | 43.124.222.234:4502 |
- Address and Port-Dependent Mapping
UDPサーバのアドレスとポートが同じなら受信したパケットのIPアドレスとポートを変換しない、そうしないと、IPアドレスやポートを変換する。
例えば:
| 送信元アドレス | 宛先アドレス | NATマッピングアドレス |
|---|---|---|
| 192.168.1.1:3000 | 1.1.1.1:3000 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.1:3000 | 43.124.222.234:4500 |
| 192.168.1.1:3000 | 1.1.1.1:3001 | 43.124.222.234:4501 |
| 192.168.1.1:3000 | 1.1.1.2:3000 | 43.124.222.234:4502 |
| 192.168.1.1:3000 | 1.1.1.3:3003 | 43.124.222.234:4503 |
Filteringの種類
フィルタリングはNAT外部から内部に送信するパケットをフィルタリングする行為です。
- Endpoint-Independent Filtering
一旦内部アドレスを外部にマッピングすると、全ての外部サーバから内部に送信することが可能です。
例えば:
| 内部アドレス | マッピング |
|---|---|
| 192.168.1.1:3000 | 43.124.222.234:4500 |
| 送信元アドレス | 宛先アドレス | 受信する? |
|---|---|---|
| 1.1.1.1:3000 | 43.124.222.234:4500 | はい 🟢 |
| 1.1.1.1:3001 | 43.124.222.234:4500 | はい 🟢 |
| 1.1.1.2:3000 | 43.124.222.234:4500 | はい 🟢 |
| 1.1.1.3:3002 | 43.124.222.234:4500 | はい 🟢 |
- Address-Dependent Filtering
内部から外部に送信したサーバ、且つアドレスも同じなら、サーバから内部に送信することが可能です。
例えば:
| 内部アドレス | マッピング | 送信歴史 宛先アドレス |
|---|---|---|
| 192.168.1.1:3000 | 43.124.222.234:4500 | 1.1.1.1:3000 |
| 送信元アドレス | 宛先アドレス | 受信する? |
|---|---|---|
| 1.1.1.1:3000 | 43.124.222.234:4500 | はい 🟢 |
| 1.1.1.1:3001 | 43.124.222.234:4500 | はい 🟢 |
| 1.1.1.2:3000 | 43.124.222.234:4500 | ダメ ❌ |
| 1.1.1.3:3002 | 43.124.222.234:4500 | ダメ ❌ |
- Address and Port-Dependent Filtering
内部から外部に送信したサーバ、且つアドレスとポートも同じなら、サーバから内部に送信することが可能です。
例えば:
| 内部アドレス | マッピング | 送信歴史 宛先アドレス |
|---|---|---|
| 192.168.1.1:3000 | 43.124.222.234:4500 | 1.1.1.1:3000 |
| 送信元アドレス | 宛先アドレス | 受信する? |
|---|---|---|
| 1.1.1.1:3000 | 43.124.222.234:4500 | はい 🟢 |
| 1.1.1.1:3001 | 43.124.222.234:4500 | ダメ ❌ |
| 1.1.1.2:3000 | 43.124.222.234:4500 | ダメ ❌ |
| 1.1.1.3:3002 | 43.124.222.234:4500 | ダメ ❌ |
Fullcone NAT
Fullcone NATはEndpoint-Independent FilteringとEndpoint-Independent Mappingです。
goで実現する
最も重要なのはNATテーブルの実現です。
// NATテーブル// キーはプロキシクライアントの送信元アドレス// 値はマッピングしたUDPサーバnatTable := map[string]net.PacketConn{} getTargetAddress := func([]byte) (*net.UDPAddr, []byte) { // TODO implement proxy protocol return nil, nil} packetResponse := func(net.Addr, []byte) []byte { // TODO implement proxy protocol return nil} // mockのUDPプロキシサーバpc, err := net.ListenPacket("udp", "")if err != nil { panic(err)}defer pc.Close() for { // IPプロトコルによってパケット最大は65535です。 buf := make([]byte, 65535) n, addr, err := pc.ReadFrom(buf) if err != nil { panic(err) } // クライアントのアドレスでマッピングサーバを保存して conn, ok := natTable[addr.String()] if !ok { // マッピングサーバを作ります conn, err = net.ListenPacket("udp", "") if err != nil { panic(err) } go func() { defer conn.Close() for { buf := make([]byte, 65535) // リモートサーバ(target)の返信を受信する n, src, err := conn.ReadFrom(buf) if err != nil { panic(err) } // レスポンスデータをクライアントに返信して _, err = pc.WriteTo(packetResponse(src, buf[:n]), addr) if err != nil { panic(err) } } }() // 初めてマッピングサーバをNATテーブルに保存して natTable[addr.String()] = conn } target, remain := getTargetAddress(buf[:n]) // リモートサーバにデータを送信して _, err = conn.WriteTo(remain, target) if err != nil { panic(err) }}
0 件のコメント