Winny/Share監視制御

本設定例では、ルーターのL2MSコントローラー機能・Luaスクリプト機能と、L2スイッチのL2MSスレーブ機能を使用しています。

ルーターの対応機種は、RTX1210RTX1200(Open in new windowRev.10.01.16以降)、RTX810NVR700WNVR510NVR500
FWX120です。

L2スイッチの対応機種は、SWX2300-8GSWX2300-16GSWX2300-24GSWX2200-8GSWX2200-24G
SWX2200-8PoESWX2100-8GSWX2100-16Gです。

L2MSコントローラー(ルーター)とL2MSスレーブ(L2スイッチ)の対応リビジョンは、Open in new window 技術資料「L2MS」でご確認ください。

図 Luaスクリプト構成図1
図 Luaスクリプト構成図2

Winnyフィルタ機能およびShareフィルタ機能を利用して、Winnyパケット、Shareパケットを監視し、発見した際には当該パケットを破棄します。また、Luaスクリプトによって、WinnyおよびShareを使用したホストが接続されたSWX2200のポートを閉じ、ホストからの通信を一定時間遮断します。
検知した内容は管理者宛てにメールで通知することもできます。

光回線に接続するためには、別途ONUが必要です。
NVR700WとNVR510は、本体のONUポートに小型ONUを装着することで、光回線に接続できます。

対応機種のうち、設定例を掲載している機種は、以下のとおりです。

機種 掲載内容 備考
ルーター

RTX1210 RTX1200 RTX810 NVR500

コマンド設定例
Luaスクリプト例

L2MSコントローラー機能、
Luaスクリプト機能

L2スイッチ

SWX2200-8G SWX2200-24G SWX2200-8PoE

L2MSスレーブ機能

LANの
インタフェースの設定
(LAN1ポートを使用)

ip lan1 address 192.168.0.1/24

WANの
インタフェースの設定
(LAN2ポートを使用)

pp select 1
pp always-on on
pppoe use lan2
pp auth accept pap chap
pp auth myname (ISPに接続するID) (ISPに接続するパスワード)
ppp lcp mru on 1454
ppp ipcp ipaddress on
ppp ipcp msext on
ip pp mtu 1454
ip pp nat descriptor 1
pp enable 1
ip route default gateway pp 1

NATの設定

nat descriptor type 1 masquerade

DHCPの設定

dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.0.2-192.168.0.100/24

DNSの設定

dns server (ISPより指定されたDNSサーバのIPアドレス)
dns private address spoof on

SYSLOGの設定

syslog notice on

SWX2200の設定

switch control use lan1 on

Winny/Shareフィルタの設定

pp select 1
ip pp intrusion detection out on
ip pp intrusion detection out winny on reject=on
ip pp intrusion detection out share on reject=on
ip pp intrusion detection out default off
pp enable 1

フィルタの設定

ip filter source-route on
ip filter directed-broadcast on
ip filter 1010 reject * * udp,tcp 135 *
ip filter 1011 reject * * udp,tcp * 135
ip filter 1012 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 1013 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 1014 reject * * udp,tcp 445 *
ip filter 1015 reject * * udp,tcp * 445
ip filter 1020 reject 192.168.0.0/24 *
ip filter 1030 pass * 192.168.0.0/24 icmp
ip filter 2000 reject * *
ip filter 3000 pass * *
ip filter dynamic 100 * * ftp
ip filter dynamic 101 * * www
ip filter dynamic 102 * * domain
ip filter dynamic 103 * * smtp
ip filter dynamic 104 * * pop3
ip filter dynamic 105 * * netmeeting
ip filter dynamic 106 * * tcp
ip filter dynamic 107 * * udp
pp select 1
ip pp secure filter in 1020 1030 2000
ip pp secure filter out 1010 1011 1012 1013 1014 1015 3000 dynamic 100 101 102 103 104 105 106 107
pp enable 1

Luaスクリプトのスケジュール設定

schedule at 1 startup * lua /swx2200_lua_winny_share_rtx1200.lua

設定値

-- RTX1200 の LAN インタフェースの数
num_lan = 1

-- パケット検出時にメールを送信するか否か(on..送信する、off..送信しない)
mail_send = "off"

-- メールの設定
mail_tbl = {
  smtp_address = "(SMTPサーバのアドレス)",
  from = "(送信元のメールアドレス)",
  to = "(宛先のメールアドレス)"
}

-- メールの送信に失敗した時に出力する SYSLOG のレベル (info, debug, notice)
log_level = "info"

-- ポートの遮断からのタイムアウト
timeout = 300

-- 遮断しているポートの数
cnt = 0

-- ポートを遮断されているホスト情報のテーブル
host_tbl = {}

ホスト検索の関数

function search(mac, addr, lan)
  -- ホスト検索結果の経路を格納
  route = nil
  -- ホスト検索結果の経路から一つ前の経路を格納
  switchroute = nil
  -- ホストが接続されているポート番号を格納
  hostport = nil

  -- LAN1のMACアドレステーブルでホストが見つかった場合
  if (lan == 1) then
    rtn, str = rt.command("show status switching-hub macaddress " ..mac)
    port = string.match(str,"port (%d):")
    if (port ~= nil) then
      route = "LAN1:" ..port
      switchroute = "RTX1200"
      hostport = port
    else
      route = nil
      switchroute = nil
      hostport = addr
    end
  else
    -- LAN2またはLAN3でホストが見つかった場合
    lan = tostring(lan)
    route = "LAN"..lan
    switchroute = "RTX1200"
    hostport = "LAN"..lan
  end

  --[[
  上記いずれかの方法でホストが見つかった場合、routeの値を基点とした経路で
  ホストが見つかるまで繰り返し検索する
  ]]
  while (true) do
    if (route ~= nil) then
      rtn, str = rt.command("switch control function get status-macaddress-addr "
                     ..mac .." " ..route)
      if (rtn) and (str ~= "0 entry\r\n") then
        switchroute = route
        hostport = string.match(str,"%d+")
        route = route .."-" ..string.match(str,"%d+")
      else
        route = nil
      end
    else
      break
    end
  end
  return switchroute, hostport
end

メールを送信する関数

function send_mail(apl, addr, macaddr, route, port)
  local rtn, str

  mail_tbl.text = string.format("%sパケットを検出したため、switch(%s)の"..
                    "ポート%dを閉じました。\r\n\r\n", apl, route, port)
  mail_tbl.text = mail_tbl.text .. "送信元ホスト情報\r\n\tIPアドレス:" .. addr .. "\r\n"
  mail_tbl.text = mail_tbl.text .. "\tMACアドレス:" .. macaddr
  mail_tbl.subject = string.format("%s packet detected", apl)
  rtn = rt.mail(mail_tbl)

  if (not rtn) then
    rt.syslog(log_level, "failed to send mail. swx2200_lua_winny_share_rtx1200.lua")
  end
end

switch controlコマンドの実行関数

function exec_sw_cmd(route, cmd)
  rtn, str = rt.command("switch select "..route)
  if (rtn) then
    rtn, str = rt.command(cmd)
  end
  return rtn
end

インターバルタイマ処理の関数

function update_host_info()
  local host_info = {}
  local i = #host_tbl

  while (i >= 1) do
    host_info = host_tbl[i]
    host_info.timeout = host_info.timeout - 1

    if (host_info.timeout <= 0) then
      str = "no switch control function set port-use " ..host_info.port
      rtn = exec_sw_cmd(host_info.route, str)
      if (rtn) then
        rt.syslog(log_level, "switch("..host_info.route..") port"..host_info.port.." UP")
        while (true) do
          table.remove(host_info)
          if (#host_info < 1) then
            break
          end
        end
        table.remove(host_tbl, i)
        cnt = cnt - 1
      else
        host_tbl[i] = host_info
      end
    end
    i = i - 1
  end
end

ホストテーブルの検索/追加をする関数

function add_host(ipaddr, switchroute, hostport)
  local host_info = {}
  local add_info = {}
  local find = 0

  for j = 1, #host_tbl do
    host_info = host_tbl[j]
    if (host_info.ipaddr == ipaddr) then
      find = 1
      host_info.timeout = timeout
      host_info.route = switchroute
      host_info.port = hostport
      host_tbl[j] = host_info
      break
    end
  end

  if (find == 0) then
    j = #host_tbl + 1
    add_info.ipaddr = ipaddr
    add_info.timeout = timeout
    add_info.route = switchroute
    add_info.port = hostport
    host_tbl[j] = add_info
    cnt = cnt + 1
  end
end

メインルーチン

local rtn, str, app, ipaddr, mac
local j = 0
local find = 0
-- Winny/Share パケットを検出した際に出力される SYSLOG の文字列パターン
ptn = "([SW][hi][an][rn][ey]) version .-"

while (true) do
  rtn, str = rt.syslogwatch(ptn, 1,1)
  if (cnt > 0) then
    update_host_info()
  end

  if (rtn > 0) and (str) then
    app = string.match(str[1], ptn)
    if (app == "Winny") or (app == "Share") then
      if (app == "Winny") then
        ipaddr = string.match(str[1], "(%d+%.%d+%.%d+%.%d+)")
      else
        ipaddr = string.match(str[1], "> (%d+%.%d+%.%d+%.%d+)")
      end

      for i = 1, num_lan do
        rtn, str = rt.command("show arp lan" .. i .. " | grep " .. ipaddr)
        if (rtn) and (str) and (string.match(str, ipaddr) ~= nil) then
          mac = string.match(str, "(%x%x:%x%x:%x%x:%x%x:%x%x:%x%x)")
          if (mac ~= nil) then
            switchroute, hostport = search(mac, ipaddr, i)
            if (switchroute ~= nil) then
              str = "switch control function set port-use " ..hostport .." off"
              rtn = exec_sw_cmd(switchroute, str)
              if (rtn) then
                if (mail_send == "on") then
                  send_mail(app, ipaddr, mac, switchroute, hostport)
                end
                rt.syslog(log_level, app.." packet detected from "..ipaddr..
                      " swx2200_lua_winny_share_rtx1200.lua")
                add_host(ipaddr, switchroute, hostport)
                break
              end
            end
          else
            rt.syslog(log_level, "[ERROR] not found MAC Address "..
                  "swx2200_lua_winny_share_rtx1200.lua")
          end
        end
      end
    end
  end
end

【ご注意】

本設定例は、設定の参考例を示したもので、動作を保証するものではございません。
ご利用いただく際には、十分に評価・検証を実施してください。

ページトップへ戻るReturn to Top