🙆
Go言語でのIPアドレスの扱い方
はじめに
このページではGo言語でのIPアドレスの扱い方について記述します。
1. IPアドレスのパースと生成
Go言語では標準ライブラリの net
パッケージを使用して、IPアドレスの操作を簡単に行うことができます。
IPアドレスのパース
net.ParseIP
関数を使って、文字列からIPアドレスをパースすることができます。
package main
import (
"fmt"
"net"
)
func main() {
ip := net.ParseIP("192.168.1.1")
if ip == nil {
fmt.Println("Invalid IP address")
} else {
fmt.Println("Parsed IP:", ip)
}
}
IPv4だけでなく、IPv6のパースも同様に行うことができます。
ip := net.ParseIP("::1") // IPv6
IPアドレスの生成
生成する場合、net.IP
型を直接使用してIPアドレスを作成できます。例えば、以下のように4バイト配列でIPv4アドレスを生成します。
ip := net.IPv4(192, 168, 1, 1)
fmt.Println("Generated IP:", ip)
2. IPアドレスのチェック
GoではIPアドレスの種類を確認するためのメソッドがいくつか用意されています。
-
IsLoopback()
: ループバックアドレスかどうか確認 -
IsPrivate()
: プライベートアドレスかどうか確認 -
IsGlobalUnicast()
: グローバルユニキャストアドレスかどうか確認
package main
import (
"fmt"
"net"
)
func main() {
ip := net.ParseIP("192.168.1.1")
if ip.IsPrivate() {
fmt.Println("This is a private IP address")
}
}
3. ホスト名からIPアドレスを解決
net.LookupIP
を使うことで、ホスト名からIPアドレスを取得することができます。
package main
import (
"fmt"
"net"
)
func main() {
ips, err := net.LookupIP("example.com")
if err != nil {
fmt.Println("Failed to lookup IP:", err)
return
}
for _, ip := range ips {
fmt.Println("IP address:", ip)
}
}
4. CIDRブロックでのIPアドレスの扱い
CIDR (Classless Inter-Domain Routing) ブロックでIPアドレスを扱う場合、net.IPNet
型を使用します。ParseCIDR
関数を使ってCIDRブロックをパースすることができます。
package main
import (
"fmt"
"net"
)
func main() {
_, ipNet, err := net.ParseCIDR("192.168.0.0/16")
if err != nil {
fmt.Println("Invalid CIDR block:", err)
return
}
fmt.Println("CIDR block:", ipNet)
}
CIDRブロック内に特定のIPアドレスが含まれているかを確認するには、Contains
メソッドを使用します。
ip := net.ParseIP("192.168.1.1")
if ipNet.Contains(ip) {
fmt.Println("IP is within the CIDR block")
}
5. IPアドレスの比較
net.IP
型のIPアドレス同士を比較する場合、Goの標準比較演算子 ==
は使えません。代わりに Equal
メソッドを使用します。
package main
import (
"fmt"
"net"
)
func main() {
ip1 := net.ParseIP("192.168.1.1")
ip2 := net.ParseIP("192.168.1.1")
if ip1.Equal(ip2) {
fmt.Println("The IP addresses are equal")
} else {
fmt.Println("The IP addresses are not equal")
}
}
6. IPアドレス制限をかけたAPIの実装例
特定のIPアドレスからのアクセスのみ許可するAPIの例を以下に示します。net.ParseIP
を使ってアクセス元のIPアドレスをチェックします。
package main
import (
"fmt"
"net"
"net/http"
)
func main() {
allowedIP := net.ParseIP("192.168.1.1")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
http.Error(w, "Invalid IP address", http.StatusForbidden)
return
}
clientIP := net.ParseIP(ip)
if clientIP == nil || !clientIP.Equal(allowedIP) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
fmt.Fprintf(w, "Hello, %s", clientIP)
})
http.ListenAndServe(":8080", nil)
}
7. CIDRブロックを使ったIP制限
特定のCIDRブロック内のIPアドレスからのみアクセスを許可する例です。
package main
import (
"fmt"
"net"
"net/http"
)
func main() {
_, allowedCIDR, _ := net.ParseCIDR("192.168.0.0/16")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
http.Error(w, "Invalid IP address", http.StatusForbidden)
return
}
clientIP := net.ParseIP(ip)
if clientIP == nil || !allowedCIDR.Contains(clientIP) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
fmt.Fprintf(w, "Hello, %s", clientIP)
})
http.ListenAndServe(":8080", nil)
}
まとめ
Go言語では、net
パッケージを使ってIPアドレスの操作やチェック、CIDRブロックでの扱いが簡単に行えます。また、IP制限をかけたAPIの実装も可能です。
Discussion