はじめに
きっと世界にはこんなことを思っている人がたくさんいるはず
- サーバが建てたい!でもグローバルにIPを出すのはやだ!
- うちの回線でポートを開きたくない!
- 複雑なネットワーク設定やセキュリティが心配...
ワカルヨソノキモチ
そんなあなたに!
自宅のでポートを開かずともサーバを公開する方法を紹介するYO
しかも、UDP対応なのでどんどんいろんなゲームでサーバ運営してね
そもそも...
なぜこんなことをしたのかは前の記事を見てね
この記事でわかること
- さくらのVPSをゲートウェイとしたTailscale VPN環境の構築方法
- 外部からのアクセスをTailscale VPN内のサーバーに転送するためのiptables (DNAT/SNAT) 設定
- ufwを併用したファイアウォール管理
- DDoS対策の基本的な考え方と設定
前記事のクライアントグローバルIPをバックエンド迄伝える方法はまた別の記事で.
Exit nodeに設定すればできちゃうけどね!!
今回実現する構成
プレイヤーからの接続は、まずさくらのVPSのグローバルIPアドレスに到達します。
そこからTailscale VPNを介して自宅のゲームサーバーへと安全に転送されます。

前提条件
- VPSを契約していること
- 筆者はさくらのVPSを利用
- ちょっとでもCLI操作とUFWのことがわかる
- VPSのパケットフィルタを設定できる(ここでは説明しないため)
注意
・ネットワーク関連の設定をかなり触るので、自己責任でお願いします。
設定手順
1. tailscaleの設定
導入方法については他様の説明がわかりやすかったのでそちらを参照
インストール後、各サーバーでTailscaleにログインし、VPNネットワークに参加させます。
sudo tailscale up
このコマンドを実行すると、認証用のURLが表示されます。そのURLをWebブラウザで開き、Tailscaleアカウントでログインしてデバイスを承認します。
ログイン後、各サーバーにTailscale IPアドレスが割り当てられます。
(例: VPS_TailscaleIP: 100.100.16.106、ゲームサーバ-TailscaleIP: 100.65.30.100)
以降はこのipアドレスを例に解説します
2. さくらのVPS の設定
さくらのVPSが外部からの接続を受け付け、Tailscale VPN内のゲームサーバーに転送するように設定します。
スクリプトファイルで以下の設定を完了することが出来ます!!![]()
※追記(2025-7-25)
iptables吹っ飛ばしてかえって弱くなってるので、Claudeと一緒に考えたセキュリティルール追加しました。
#!/bin/bash
# ===================================================================
# --- ▼▼▼ あなたの環境に合わせて必ず編集してください ▼▼▼ ---
# ===================================================================
# ゲームサーバーのTailscale IPアドレス
GAME_SERVER_TS_IP="100.x.x.x"
# ★★★ さくらVPS自身のTailscale IPアドレス ★★★
VPS_TS_IP="100.x.x.y"
# 転送したいUDPポート (例: "28015" 複数の場合は"28015,28016"というようにカンマで分ける)
GAME_PORTS_UDP=""
# 転送したいTCPポート (例: "28016"複数の場合は"28015,28016"というようにカンマで分ける)
GAME_PORTS_TCP=""
# VPSのパブリック・ネットワークインターフェース名
PUBLIC_IF="インターフェイス名"
# Tailscaleのネットワークインターフェース名
TAILSCALE_IF="tailscale0"
# ===================================================================
# --- ▲▲▲ 編集はここまで ▲▲▲ ---
# ===================================================================
# --- 変数チェック ---
if [ "$GAME_SERVER_TS_IP" == "100.x.x.x" ] || [ "$VPS_TS_IP" == "100.x.x.y" ]; then
echo "【エラー】スクリプトを編集して、GAME_SERVER_TS_IP と VPS_TS_IP を設定してください。"
exit 1
fi
echo "--- Starting Proxy Gateway Configuration ---"
# --- 1. IPフォワーディング有効化 ---
sudo sysctl -w net.ipv4.ip_forward=1
# --- 2. iptables初期化 ---
echo "Resetting iptables rules..."
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -F
sudo iptables -X
# --- 3. 基本的なファイアウォールルール ---
echo "Applying basic firewall rules..."
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# --- 3.5. 強力なセキュリティ・DDoS対策ルール ---
echo "Applying strong security and DDoS protection rules..."
# === DDoS対策 ===
# SYNフラッド対策
sudo iptables -A INPUT -p tcp --syn -m limit --limit 20/s --limit-burst 50 -j ACCEPT
sudo iptables -A INPUT -p tcp --syn -j DROP
# 大量の同時接続制限
sudo iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 400 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
# ICMP flood対策
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 1 -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
# UDP flood対策
sudo iptables -A INPUT -p udp -m limit --limit 200/s --limit-burst 100 -j ACCEPT
sudo iptables -A INPUT -p udp -j DROP
# === 悪意のあるパケット対策 ===
# 無効なパケットのドロップ
sudo iptables -A INPUT -m state --state INVALID -j DROP
# 不正なTCPフラグのドロップ
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# Xmas攻撃とNull攻撃の防御
sudo iptables -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL FIN -j DROP
# === ポートスキャン・ブルートフォース対策 ===
# SSH Brute Force対策
sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH-Excess: "
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
# === ゲームポート保護 ===
# 大規模Rustサーバーの特性を考慮した接続頻度制限
for port in `echo "$GAME_PORTS_TCP" | tr "," "\n"`
do
# TCP: 500接続/分をlimitで実装
sudo iptables -A INPUT -p tcp --dport "$port" -m limit --limit 8/s --limit-burst 50 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport "$port" -j LOG --log-prefix "TCP-Limit-$port: "
sudo iptables -A INPUT -p tcp --dport "$port" -j DROP
done
for port in `echo "$GAME_PORTS_UDP" | tr "," "\n"`
do
# UDP: 2000パケット/分をlimitで実装
sudo iptables -A INPUT -p udp --dport "$port" -m limit --limit 33/s --limit-burst 200 -j ACCEPT
sudo iptables -A INPUT -p udp --dport "$port" -j LOG --log-prefix "UDP-Limit-$port: "
sudo iptables -A INPUT -p udp --dport "$port" -j DROP
done
# Tailscaleトラフィックの許可(バックエンド通信)
sudo iptables -A INPUT -i "$TAILSCALE_IF" -j ACCEPT
# === 地理的制限(オプション:特定地域からのアクセス制限) ===
# 以下はコメントアウトしておきます。必要に応じて有効化してください。
# sudo iptables -A INPUT -m geoip --src-cc CN,RU,KP -j DROP
# === 接続追跡テーブルの保護 ===
# 接続追跡テーブルの過負荷を防ぐ
echo 131072 > /proc/sys/net/netfilter/nf_conntrack_max
echo 30 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_fin_wait
echo 60 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait
# --- 4. 転送(FORWARD)とNATルール ---
echo "Applying FORWARD and NAT rules..."
# === FORWARD チェーンのセキュリティ強化 ===
# 無効なパケットの転送を拒否
sudo iptables -A FORWARD -m state --state INVALID -j DROP
# 不正なTCPフラグを持つパケットの転送を拒否
sudo iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -A FORWARD -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
sudo iptables -A FORWARD -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# バックエンドサーバーへの転送レート制限
for port in `echo "$GAME_PORTS_TCP" | tr "," "\n"`
do
# TCP転送の制限(10接続/秒 = 600接続/分)
sudo iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -p tcp --dport "$port" -m limit --limit 10/s --limit-burst 60 -j ACCEPT
sudo iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -p tcp --dport "$port" -j LOG --log-prefix "FWD-TCP-Limit-$port: "
sudo iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -p tcp --dport "$port" -j DROP
done
for port in `echo "$GAME_PORTS_UDP" | tr "," "\n"`
do
# UDP転送の制限(42パケット/秒 = 2500パケット/分)
sudo iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -p udp --dport "$port" -m limit --limit 42/s --limit-burst 250 -j ACCEPT
sudo iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -p udp --dport "$port" -j LOG --log-prefix "FWD-UDP-Limit-$port: "
sudo iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -p udp --dport "$port" -j DROP
done
# FORWARDルール: 確立済みの通信はすべて許可
sudo iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# NATルール
# DNAT (宛先書き換え): 外部->VPS を 外部->ゲームサーバー に
if [ ! -z "$GAME_PORTS_UDP" ]; then
sudo iptables -t nat -A PREROUTING -i $PUBLIC_IF -p udp -m multiport --dports $GAME_PORTS_UDP -j DNAT --to-destination $GAME_SERVER_TS_IP
fi
if [ ! -z "$GAME_PORTS_TCP" ]; then
sudo iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp -m multiport --dports $GAME_PORTS_TCP -j DNAT --to-destination $GAME_SERVER_TS_IP
fi
# ★★★ SNAT (送信元書き換え): 外部->ゲームサーバー の通信元を「VPSのTailscale IP」に書き換える
sudo iptables -t nat -A POSTROUTING -o $TAILSCALE_IF -d $GAME_SERVER_TS_IP -j SNAT --to-source $VPS_TS_IP
# MASQUERADE: ゲームサーバーからの応答がVPSからプレイヤーへ返る際の送信元を「VPSのグローバルIP」に書き換える
sudo iptables -t nat -A POSTROUTING -o $PUBLIC_IF -j MASQUERADE
# --- 5. 最終的なセキュリティポリシーとログ設定 ---
echo "Applying final security policies and logging..."
# 全ての拒否されたパケットをログに記録(制限付き)
sudo iptables -A INPUT -m limit --limit 2/min --limit-burst 2 -j LOG --log-prefix "VPS-INPUT-DROP: " --log-level 4
sudo iptables -A FORWARD -m limit --limit 2/min --limit-burst 2 -j LOG --log-prefix "VPS-FORWARD-DROP: " --log-level 4
# デフォルトポリシーを拒否に設定(より安全)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# 最終的な拒否ルール
sudo iptables -A INPUT -j DROP
sudo iptables -A FORWARD -j DROP
echo "--- Configuration Complete! ---"
echo "--- Strong security and DDoS protection applied ---"
echo "--- Backend server is now protected by proxy firewall ---"
・chmod +x setup_gateway.sh で実行権限を付与します。
・sudo ./setup_gateway.sh でスクリプトを実行します。
iptables NATルールの設定
初期バージョンからほとんど変えてないので
スクリプトの方を使っちゃった方が安全です。
ip forwardの許可
- 一時的な有効化
sudo sysctl -w net.ipv4.ip_forward=1
- 恒久的な有効化
# /etc/sysctl.conf を編集し、以下の行を追加またはコメント解除
- # net.ipv4.ip_forward = 1
+ net.ipv4.ip_forward = 1
# 編集後、sudo sysctl -p を実行して適用
1. DNAT (Destination Network Address Translation)
プレイヤーからの接続をゲームサーバーのTailscale IPアドレスに転送します。
この時、外部に出るインターフェイスの選択が必須になるので"ip a"なりで確認しておくこと
# TCPポート のDNAT
sudo iptables -t nat -A PREROUTING -i <インターフェイス名> -p tcp --dport <ポート番号> -j DNAT --to-destination <ゲームサーバ-TailscaleIP>:<ポート番号>
# UDPポート のDNAT
sudo iptables -t nat -A PREROUTING -i <インターフェイス名> -p udp --dport <ポート番号> -j DNAT --to-destination <ゲームサーバ-TailscaleIP>:<ポート番号>
2. SNAT (Source Network Address Translation) の簡略化
ゲームサーバーへの送信元IPアドレスをさくらのVPSのTailscale IPに変換します。
これにより、ゲームサーバーは応答をさくらのVPSに正しく返します。
# より汎用的なMASQUERADEルールを追加
sudo iptables -t nat -A POSTROUTING -o tailscale0 -j MASQUERADE
そもそもこれって何してんの?
Tailscaleのネットワーク内(Tailnet)を通過しても、宛先が迷子になってしまう。
それを、特定のポートにアクセスが来た場合にはゲームサーバに宛先を変更してあげている。(D-NAT)
また、返答先をVPSにするように、接続元IPはVPSであるとゲームサーバに伝えてあげている。(S-NAT)
3. UFW INPUT/FORWARDルールの設定
さくらのVPSのufw設定を確認し、必要なポートが適切に許可されているか確認します。
# これらのルールはufw-user-forwardチェーンに追加されます
sudo ufw route allow in on <インターフェイス名> out on tailscale0 to <ゲームサーバ-TailscaleIP> port <ポート番号> proto tcp
sudo ufw route allow in on <インターフェイス名> out on tailscale0 to <ゲームサーバ-TailscaleIP> port <ポート番号> proto udp
# 設定を反映
sudo ufw reload
4. ファイアウォールのあれこれ (さくらのVPS側)
基本的なDDoS対策やブルートフォース攻撃対策等として、特定のポートへの接続レートを制限します。
bashで実行可能なshファイルを作って、実行権限を渡してsudoで実行してください。
気持ちばかりの設定なので、完全には防げません。
# 転送したいUDPポート (例: "28015" 複数の場合は"28015,28016"というようにカンマで分ける)
GAME_PORTS_UDP=""
# 転送したいTCPポート (例: "28016"複数の場合は"28015,28016"というようにカンマで分ける)
GAME_PORTS_TCP=""
# --- 基本的なファイアウォールルール ---
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# 大量の同時接続制限(300人対応)
sudo iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 400 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
# ICMP flood対策(より厳格)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 1 -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
# UDP flood対策(300人対応)
sudo iptables -A INPUT -p udp -m limit --limit 200/s --limit-burst 100 -j ACCEPT
sudo iptables -A INPUT -p udp -j DROP
# === 悪意のあるパケット対策 ===
# 無効なパケットのドロップ
sudo iptables -A INPUT -m state --state INVALID -j DROP
# 不正なTCPフラグのドロップ
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# Xmas攻撃とNull攻撃の防御
sudo iptables -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL FIN -j DROP
# === ポートスキャン・ブルートフォース対策 ===
# SSH Brute Force対策(改良版)
sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH-Excess: "
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
# === ゲームポート保護(300人対応・改良版) ===
# 大規模Rustサーバーの特性を考慮した接続頻度制限
for port in `echo "$GAME_PORTS_TCP" | tr "," "\n"`
do
# TCP: 500接続/分をlimitで実装
sudo iptables -A INPUT -p tcp --dport "$port" -m limit --limit 8/s --limit-burst 50 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport "$port" -j LOG --log-prefix "TCP-Limit-$port: "
sudo iptables -A INPUT -p tcp --dport "$port" -j DROP
done
for port in `echo "$GAME_PORTS_UDP" | tr "," "\n"`
do
# UDP: 2000パケット/分をlimitで実装
sudo iptables -A INPUT -p udp --dport "$port" -m limit --limit 33/s --limit-burst 200 -j ACCEPT
sudo iptables -A INPUT -p udp --dport "$port" -j LOG --log-prefix "UDP-Limit-$port: "
sudo iptables -A INPUT -p udp --dport "$port" -j DROP
done
# Tailscaleトラフィックの許可(バックエンド通信)
sudo iptables -A INPUT -i "$TAILSCALE_IF" -j ACCEPT
# === 地理的制限(オプション:特定地域からのアクセス制限) ===
# 以下はコメントアウトしておきます。必要に応じて有効化してください。
# sudo iptables -A INPUT -m geoip --src-cc CN,RU,KP -j DROP
# === 接続追跡テーブルの保護(300人対応) ===
# 接続追跡テーブルの過負荷を防ぐ(大規模サーバー対応)
echo 131072 > /proc/sys/net/netfilter/nf_conntrack_max
echo 30 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_fin_wait
echo 60 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait
5. ルールの永続化
全てのiptablesルール変更後、ルールを保存します。
sudo netfilter-persistent save
3. ゲームサーバー の設定
ゲームサーバー側では、Tailscaleからのアクセスを許可し、必要なポートを開放します。
1. UFW INPUTルールの確認と簡略化
この設定では、Tailscaleからくる接続のすべてを許可しています。
ゲームに合わせていいように設定してあげることをお勧めします。
# 例(すべて許可)
sudo ufw allow from <VPS_TailscaleIP> port any proto tcp
# 例(一部ポートのみ許可)
sudo ufw allow from <VPS_TailscaleIP> port <ポート番号> proto <プロトコル>
# ufwをリロード
sudo ufw reload
動作確認
設定が完了したら、外部からの接続をテストします。
サーバーへの接続確認:
ゲームサーバで適当なゲームのサーバを立ち上げて、下記リンクから接続テストをする事
※ipはVPSのIPを利用すること
まとめ
さくらのVPSとTailscale、そしてiptables/ufwを適切に設定することで、自宅のゲームサーバーを安全かつ柔軟にインターネットに公開することができます。
DDoS対策も基本的な設定を施すことで、ある程度の攻撃に対する耐性を高められます。
この設定が、あなたのゲームサーバーライフの一助となれば幸いです。