Bloody Mary - blog

Bloody Mary 別館

VPN サーバをルータ代わりにする 3

VPN サーバをルータ化する

iptables の基本ルール

  • INPUT / OUTPUT / FORWARD は DROP。
  • 一度接続が確立された(ESTABLISHED) INPUT / OUTPUT / FORWARD は許可。

iptables のスクリプトは最後に記述するとして、初めに VPN が接続されるまでにどのようなプロトコルで送られてくるかを確認しておく。

VPN (L2TP) 接続前のルール

図を見ると VPN サーバはインターネット上にあり、 eth0 というネットワークカードにグローバルIPアドレス 1.2.3.4 が割り当てられている。

# eth0 に IN する UDP:1701, UDP:500, UDP:4500 を許可する必要がある。
$IPTABLES -A INPUT  -i eth0 -p udp -m multiport --dport 1701,500,4500 -j ACCEPT

※ $IPTABLES は iptables コマンドへのパスを表している

# L2TP で接続するために eth0 から OUT するパケットも許可する。
$IPTABLES -A OUTPUT -o eth0 -p udp -m multiport --sport 1701,500,4500 -j ACCEPT
# esp プロトコルが必須かどうかは未検証だが、面倒なので許可する
$IPTABLES -A INPUT  -i eth0 -p esp -j ACCEPT

上記の設定を行うことで、 VPN サーバと VPN クライアントは L2TP で接続される (VLAN でつながる) 。

VPN 接続後の (ルータ化)

VLAN でつながるようになったので VPN サーバのルータ化設定を行う。

VPN とインターネットの関係を簡略化するとこのようになる。

LAN とインターネットの関係とほぼ一緒ということが分かる。

図を見ると大まかに 3 種類のルールが必要となる。

SNAT (MASQUERADE)

赤いラインは VLAN (pppX) からインターネットに送られるパケットの SNAT (MASQUERADE) ルールだ。

パケットが eth0 から出ていくときに、 From の IP アドレスが 192.168.100.X になっているので、送り返されてくるパケットが行方不明になってしまう。

そこで Source IP アドレスをグローバル IP アドレスに変換することで、正常に通信できるようにする。

$IPTABLES -t nat -A POSTROUTING -o eth0 -s $VPN_RANGE -j MASQUERADE
DNAT (DMZ へのポートマップ)

青いラインはインターネット (eth0) から特定のポートに送られてくるパケットを、 DMZ の IP アドレス:ポートに変換するルールだ。

DMZ 上のサーバというのは、本来であれば LAN 内に置いた公開用 WEB サーバとかいった意味合いになるのだが、この場合は BitComet を利用したい PC の意。

$IPTABLES -t nat -A PREROUTING -i eth0 -p tcp --dport $DMZ_PORT -j DNAT --to-destination $DMZ_IP:$DMZ_PORT
VLAN の FORWARD ルール
# VLAN からインターネットに出ていくパケットを許可 (MASQUERADE 用)
$IPTABLES -A FORWARD -i ppp+ -o eth0 -j ACCEPT

# VLAN 間の FORWARD を許可
$IPTABLES -A FORWARD -i ppp+ -o ppp+ -j ACCEPT

# インターネットから DMZ に入ってくるパケットを許可
$IPTABLES -A FORWARD -i eth0 -o ppp+ -p tcp --dport $DMZ_PORT -j ACCEPT

SNAT / DNAT / FORWARD の設定をすることで、 LAN から VLAN を通ってインターネット側に通信できるようになった。

iptables アンロード設定

VPN ルータとしての利用がメインとなるため、 iptables を再起動したときに、それまで接続していたセッションが切れるのはよろしくない。

従って iptables 再起動時にモジュールをアンロードしない設定が必要となる。

この設定をしていない場合、アンロードするとそれまで ESTABLISHED だったセッションが INVALID になる = 切れる。

# vi /etc/sysconfig/iptables-config
--------------------------------------------------
  8 # Unload modules on restart and stop
  9 #   Value: yes|no,  default: yes
 10 # This option has to be 'yes' to get to a sane state for a firewall
 11 # restart or stop. Only set to 'no' if there are problems unloading netfilter
 12 # modules.
 13 IPTABLES_MODULES_UNLOAD="no"
--------------------------------------------------

※ IPTABLES_MODULES_UNLOAD を no にする。

iptables スクリプト

  • ipfilter というファイル名でスクリプトを保存する
  • ipfilter のパーミッションを 700 にする
  • ipfilter を実行する

このサーバは cloudn の 400 [円/月] のやつなので、サービスは最低限しか起動してはいけない。

まあ、ルータとして使う分には十分のはず。入れたとしても samba くらい。

ルータ機能に影響するので、間違ってもリソース食いの Apache や postfix 等の余計なサービスは起動しないこと。

# vi /root/bin/ipfilter_allow_ssh
------------------------------
5.6.7.8       # MyServer1
5.6.7.9       # MyServer2
------------------------------
※ インターネット側から SSH 許可する端末の IP アドレスを記載
※ VPN 内は全許可のルールのため、 VPN クライアントの IP アドレスをいちいち記載しておく必要はない


# vi /root/bin/ipfilter
------------------------------
(略)
------------------------------
※ 何行か下のスクリプトをコピペ
※ 自分の環境に合わせて Environment Variable を編集すること


# chmod 700 /root/bin/ipfilter
# /root/bin/ipfilter
  1. echo "# Environment Variable Setting..."
  2. ####################
  3. # Environment Variable
  4. ####################
  5.  
  6. # Network
  7. GLOBAL_IP='1.2.3.4'
  8. VPN_RANGE='192.168.100.0/24'
  9. DMZ_IP='192.168.100.200'
  10. DMZ_PORT='8080'
  11.  
  12. # Command
  13. SYSCTL='/sbin/sysctl'
  14. MODPROBE='/sbin/modprobe'
  15. IPTABLES='/sbin/iptables'
  16. SERVICE_IPTABLES='/etc/rc.d/init.d/iptables'
  17. ALLOW_SSH_FILE='/root/bin/ipfilter_allow_ssh'
  18.  
  19. # Security Parameters
  20. SYNLIMIT="10/s"           # SYN-Flood  Permit  10 times/s
  21. SYNBURST="25"             # SYN-Flood  MAX     25 times
  22. PINGLIMIT="6/s"           # PING-Flood Permit  6  times/s
  23. PINGBURST="15"            # PING-Flood MAX     15 times
  24.  
  25.  
  26. echo "# Load Module..."
  27. ####################
  28. # Load Module
  29. ####################
  30. $MODPROBE iptable_nat
  31.  
  32.  
  33. echo "# Set Kernel Parameters..."
  34. ####################
  35. # Kernel Parameters
  36. ####################
  37.  
  38. # SYN Cookies ( TCP SYN Flood )
  39. $SYSCTL -w net.ipv4.tcp_syncookies=1 > /dev/null
  40.  
  41. # Broadcast ping ( Smurf Atack )
  42. $SYSCTL -w net.ipv4.icmp_echo_ignore_broadcasts=1 > /dev/null
  43.  
  44. for dev in `ls /proc/sys/net/ipv4/conf/`
  45. do
  46.     # ICMP Redirect
  47.     $SYSCTL -w net.ipv4.conf.$dev.accept_redirects=0 > /dev/null
  48.     # Source Routed
  49.     $SYSCTL -w net.ipv4.conf.$dev.accept_source_route=0 > /dev/null
  50. done
  51.  
  52.  
  53. echo "# Initialization..."
  54. ####################
  55. # Initialization
  56. ####################
  57. $SERVICE_IPTABLES stop
  58. $IPTABLES -F
  59. $IPTABLES -X
  60. $IPTABLES -Z
  61.  
  62.  
  63. echo "# Default Rule is Drop..."
  64. ####################
  65. # Default Rule
  66. ####################
  67. $IPTABLES -P INPUT DROP
  68. $IPTABLES -P OUTPUT DROP
  69. $IPTABLES -P FORWARD DROP
  70.  
  71. ####################
  72. # Loopback
  73. ####################
  74. $IPTABLES -A INPUT  -i lo -j ACCEPT
  75. $IPTABLES -A OUTPUT -o lo -j ACCEPT
  76.  
  77. ####################
  78. # Session Established
  79. ####################
  80. $IPTABLES -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
  81. $IPTABLES -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
  82. $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
  83.  
  84.  
  85. echo "# Security Setting..."
  86. ####################
  87. # Security
  88. ####################
  89.  
  90. # Not Spoofing
  91. $IPTABLES -A INPUT -s 0.0.0.0 -d 224.0.0.0/4     -j ACCEPT
  92. $IPTABLES -A INPUT -s 0.0.0.0 -d 255.255.255.255 -j ACCEPT
  93.  
  94. # Spoofing
  95. $IPTABLES -N spoofing
  96. $IPTABLES -A spoofing -j LOG --log-prefix "iptables-Block Spoofing: "
  97. $IPTABLES -A spoofing -j DROP
  98. $IPTABLES -A INPUT -i eth0 -s 0.0.0.0/8      -j spoofing
  99. $IPTABLES -A INPUT -i eth0 -s 10.0.0.0/8     -j spoofing
  100. $IPTABLES -A INPUT -i eth0 -s 127.0.0.0/8    -j spoofing
  101. $IPTABLES -A INPUT -i eth0 -s 172.16.0.0/12  -j spoofing
  102. $IPTABLES -A INPUT -i eth0 -s 192.0.2.0/24   -j spoofing
  103. $IPTABLES -A INPUT -i eth0 -s 192.168.0.0/16 -j spoofing
  104. $IPTABLES -A INPUT -i eth0 -s 224.0.0.0/4    -j spoofing
  105. $IPTABLES -A INPUT -i eth0 -s 240.0.0.0/5    -j spoofing
  106. $IPTABLES -A INPUT -i eth0 -s 248.0.0.0/5    -j spoofing
  107. $IPTABLES -A INPUT -i eth0 -s 255.255.255.255/32 -j spoofing
  108.  
  109. # Ping flooding ( Ping of Death )
  110. $IPTABLES -N ping-flooding
  111. $IPTABLES -A ping-flooding -m limit --limit $PINGLIMIT --limit-burst $PINGBURST -j ACCEPT
  112. $IPTABLES -A ping-flooding -j LOG --log-prefix "iptables-Block Ping flood: "
  113. $IPTABLES -A ping-flooding -j DROP
  114. $IPTABLES -A INPUT  -p icmp --icmp-type echo-request -j ping-flooding
  115. $IPTABLES -A OUTPUT -p icmp --icmp-type echo-request -j ping-flooding
  116.  
  117. # Port scan
  118. $IPTABLES -N port-scan
  119. $IPTABLES -A port-scan -m limit --limit 1/s --limit-burst 4 -j RETURN
  120. $IPTABLES -A port-scan -j LOG --log-prefix "iptables-Block Port Scan: "
  121. $IPTABLES -A port-scan -j DROP
  122. $IPTABLES -A INPUT  -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j port-scan
  123. $IPTABLES -A OUTPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j port-scan
  124.  
  125. # SYN flood
  126. $IPTABLES -N syn-flood
  127. $IPTABLES -A syn-flood -p tcp -m limit --limit $SYNLIMIT --limit-burst $SYNBURST -j RETURN
  128. $IPTABLES -A syn-flood -j LOG --log-prefix "iptables-Block SYN Flood: "
  129. $IPTABLES -A syn-flood -j DROP
  130. $IPTABLES -A INPUT  -p tcp --syn -j syn-flood
  131. $IPTABLES -A OUTPUT -p tcp --syn -j syn-flood
  132.  
  133. # fragment
  134. $IPTABLES -N fragment
  135. $IPTABLES -A fragment -j LOG --log-prefix "iptables-Block Fragment: "
  136. $IPTABLES -A fragment -j DROP
  137. $IPTABLES -A INPUT -f -j fragment
  138.  
  139. # Port 113 (IDENT)
  140. $IPTABLES -N ident
  141. $IPTABLES -A ident -f -j LOG --log-prefix "iptables-Block IDENT: "
  142. $IPTABLES -A ident -f -j REJECT
  143. $IPTABLES -A INPUT -p tcp --dport 113 -j ident
  144.  
  145.  
  146. echo "# VPN Setting..."
  147. ####################
  148. # VPN Setting
  149. ####################
  150.  
  151. # L2TP (from Internet)
  152. $IPTABLES -A INPUT  -i eth0 -p udp -m multiport --dport 1701,500,4500 -j ACCEPT
  153. $IPTABLES -A OUTPUT -o eth0 -p udp -m multiport --sport 1701,500,4500 -j ACCEPT
  154. $IPTABLES -A INPUT  -i eth0 -p esp -j ACCEPT
  155.  
  156. # NetBIOS Reject (from Internet)
  157. $IPTABLES -A FORWARD -o eth0 -p tcp -m multiport --dport 135,137,138,139,445 -j DROP
  158. $IPTABLES -A FORWARD -o eth0 -p udp -m multiport --dport 135,137,138,139,445 -j DROP
  159.  
  160. # NetBIOS Allow (in VPN)
  161. $IPTABLES -A OUTPUT -o ppp+ -p tcp -m multiport --dport 135,137,138,139,445 -j ACCEPT
  162. $IPTABLES -A OUTPUT -o ppp+ -p udp -m multiport --dport 135,137,138,139,445 -j ACCEPT
  163.  
  164. # SNAT (MASQUERADE, from VPN to Internet)
  165. $IPTABLES -t nat -A POSTROUTING -o eth0 -s $VPN_RANGE -j MASQUERADE
  166.  
  167. # DNAT (DMZ, from Internet to Local Server in VPN )
  168. $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp --dport $DMZ_PORT -j DNAT --to-destination $DMZ_IP:$DMZ_PORT
  169.  
  170. # FORWARD (MASQUERADE)
  171. $IPTABLES -A FORWARD -i ppp+ -o eth0 -j ACCEPT
  172. # FORWARD (allow Request from VPN to VPN)
  173. $IPTABLES -A FORWARD -i ppp+ -o ppp+ -j ACCEPT
  174. # FORWARD (DMZ)
  175. $IPTABLES -A FORWARD -i eth0 -o ppp+ -p tcp --dport $DMZ_PORT -j ACCEPT
  176.  
  177. # Allow Request from VPN (ex. samba, ssh, etc...)
  178. $IPTABLES -A INPUT -i ppp+ -j ACCEPT
  179.  
  180.  
  181. echo "# Allow Port And Client Setting..."
  182. ####################
  183. # Allow Port And Permit Client
  184. ####################
  185.  
  186. # Traceroute Command
  187. $IPTABLES -A OUTPUT -p udp --dport 33434:33523 -m state --state NEW -j ACCEPT
  188.  
  189. # SSH Server
  190. for ip in `awk '{print $1;}' $ALLOW_SSH_FILE`
  191. do
  192.     echo "## allow ssh: $ip"
  193.     $IPTABLES -A INPUT -p tcp -s $ip --dport 22 -j ACCEPT
  194. done
  195. $IPTABLES -A OUTPUT -p tcp --sport 22 -j ACCEPT
  196.  
  197. # SSH Client
  198. $IPTABLES -A OUTPUT -p tcp --dport 22 -j ACCEPT
  199.  
  200. # WEB Client
  201. $IPTABLES -A OUTPUT -p tcp --dport 80  -j ACCEPT
  202. $IPTABLES -A OUTPUT -p tcp --dport 443 -j ACCEPT
  203.  
  204. # FTP Client
  205. $IPTABLES -A OUTPUT -p tcp --dport 20:21 -j ACCEPT
  206.  
  207. # NTP Server
  208. $IPTABLES -A INPUT  -p udp --dport 123 -j ACCEPT
  209. $IPTABLES -A OUTPUT -p udp --dport 123 -j ACCEPT
  210.  
  211. # DNS Resolve
  212. $IPTABLES -A OUTPUT -p udp --dport 53 -j ACCEPT
  213.  
  214. # WHOIS Client
  215. $IPTABLES -A OUTPUT -p tcp --dport 43 -j ACCEPT
  216. $IPTABLES -A INPUT  -p tcp --sport 43 -j ACCEPT
  217.  
  218.  
  219. echo "# INPUT / OUTPUT / FORWARD LOG..."
  220. ####################
  221. # Debug
  222. ####################
  223. $IPTABLES -A INPUT   -j LOG --log-prefix "iptables-Debug INPUT Drop: "
  224. $IPTABLES -A OUTPUT  -j LOG --log-prefix "iptables-Debug OUTPUT Drop: "
  225. $IPTABLES -A FORWARD -j LOG --log-prefix "iptables-Debug FORWARD Drop: "
  226.  
  227.  
  228. echo "# Rules Save and iptables Restart..."
  229. ####################
  230. # Save & Restart
  231. ####################
  232. $SERVICE_IPTABLES save
  233. $SERVICE_IPTABLES start

※ 223 ~ 225 行目はデバッグ用なので、必要に応じてコメントアウトすること。

echo でメッセージを表示させることで、エラーが出たとしても特定しやすくなる。まあ「# sh -x ipfilter」でデバッグすればいいことだが……

そんで Widowos7 の VPN クライアントから、前ページで作成した「hogeVPN」をダブルクリックして接続できれば OK。

ping 192.168.100.1 への反応がなかったり、そもそも VPN 接続が確立できない場合は、エラー内容に沿った対応が必要になる。

VPN 接続時のエラー (ざっくり)

私がはまったところだと次のような感じ。

ネゴシエーションのエラー
  • 設定ファイルのミス。
    最悪はカーネルが L2TP に対応していないとかだが、 /var/log/messages とかでエラー内容をググってコツコツつぶしていくしかない。
    単純なところでは事前共有鍵の入力ミスとか、 VPN 接続の [セキュリティ] タブの設定ミス。
  • VPN クライアント側で、 SoftEther などの余計なドライバがあると接続できない事象があった。
    [プログラムと機能] で SoftEther をアンインストールしてから、 [デバイスマネージャ] – [ネットワーク アダプタ] からインストールされた VPN のネットワークアダプタを削除、再起動したら接続できるようになった。
    なお [コンパネ] – [ネットワーク接続] からは上記のアダプタは削除できない。
  • もう一つ可能性が高いものは、サーバの設定ファイルがかなり怪しい。
    /etc/ipsec.d/l2tp-psk.conf を見直してみるとか、環境に合わせて別の設定にしてみるとか。と言っても具体的なアイディアはないわけだが。
パスワードのエラー
  • 設定ファイルのミス。
  • もしくは、パスワードに事前共有鍵を入れていたり、単なる入力間違い。
接続後に 192.168.100.1 に ping 飛ばない
  • iptables の FOWARD あたりがあやしい。
    とりあえず iptables のデフォルトルールを ACCEPT にしてみるとか?
    もちろん、それで通信できたからといってそのままの設定で使わず、必ず原因を究明すること。でないとセキュリティもへったくれもない。

おまけ VPN サービス起動スクリプト

使い方の一例
  • # vpnctl fullrestart
    VPN サービスの再起動 & ipfilter の実行
  • # vpnctl log
    /var/log/messages のリアルタイムログ (tailf コマンド)
スクリプト
# vi /root/bin/vpnctl
------------------------------
(下のやつ)
------------------------------

# chmod 700 /root/bin/vpnctl

# vpnctl fullrestart (とりあえず再起動)
  1. #!/bin/sh
  2.  
  3. SERVICE='/sbin/service'
  4. IPFILTER='/root/bin/ipfilter'
  5. TAILF='/usr/bin/tailf'
  6.  
  7. ERROR=0
  8.  
  9. case "$1" in
  10.  
  11.   start)
  12.     $SERVICE xl2tpd start
  13.     $SERVICE ipsec  start
  14.     ;;
  15.  
  16.   fullstart)
  17.     $0 start
  18.     $IPFILTER
  19.     ;;
  20.  
  21.   stop)
  22.     $SERVICE xl2tpd stop
  23.     $SERVICE ipsec  stop
  24.     ;;
  25.  
  26.   restart)
  27.     $0 stop
  28.     $0 start
  29.     exit $?
  30.     ;;
  31.  
  32.   fullrestart)
  33.     $0 stop
  34.     $0 fullstart
  35.     exit $?
  36.     ;;
  37.  
  38.   log)
  39.     echo -e "\n\n############################## Stop the Log-View : press Ctrl-C key\n"
  40.     $TAILF /var/log/messages
  41.     exit $?
  42.     ;;
  43.  
  44.  
  45.   *)
  46.     echo "Usage: vpnctl (start|stop|restart|fullstart|fullrestart|log)"
  47.     exit 1
  48.  
  49. esac
  50.  
  51. exit $ERROR

とりあえずこんなカンジだろうか。

次はおまけの samba インストール設定。

Updated: 2015/3/2 月曜日 — 12:21:35

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Bloody Mary - blog © 2008 - 2021