Luaでの接続処理

このセクションの内容:

概要

接続処理のスクリプトにおける要件

使用中のテーブル

利用可能な補助モジュール

概要

Dr.Web Firewall for LinuxはLuaのプログラムインタプリタを介して対話をサポートします(バージョン5.3.4が使用され、Dr.Web for UNIX Internet Gatewaysと一緒に提供されます)。Luaで書かれたスクリプトは、解析のためにSpIDer Gateに送信される前に、事前接続スキャンのためにコンポーネントによって使用されます。

Dr.Web Firewall for Linux設定(InterceptHookパラメータ内)が次のパスで指定されている場合、Luaスクリプトを使用した接続解析が、接続スキャンのスクリプトを含む、Luaで書かれたファイルに実行されます。それ以外の場合は、コンポーネント設定で指定されているデフォルト設定と処理ルール(RuleSet*パラメータ)を使用して接続処理が実行されます。

接続処理用のLuaスクリプトのその他の例については、次のリンクからご確認ください。
https://github.com/DoctorWebLtd/drweb-lua-examples/tree/master/firewall

接続処理のスクリプトにおける要件

このファイルには、接続スキャンモジュールのエントリポイントであるグローバル関数が含まれている必要があります(Dr.Web Firewall for Linuxは、新しく受信した接続を処理するためにこの関数を呼び出します)。処理関数は、次の呼び出し規則を満たす必要があります。

1.関数名 - intercept_hook;

2.引数は、Luaコンテキストテーブルのみです(処理された接続の関数からの情報へのアクセスを提供します。以下の表の説明を参照してください)。

3.戻り値は、以下の表の文字列値のみです。

判定の説明

pass

SpIDer Gateによるスキャンを行わずに接続をスキップする

check

SpIDer Gateを使用して接続をスキャンする

drop

パケット損失で接続をブロックする

reject

接続を破棄する(接続を開始し、RSTフラグ付きのTCPパケットを受信するクライアント)

1.すべての接続について無条件にpass判定(スキップ)を返すLuaスクリプト。

-- Function of connection scanning written by the user
function intercept_hook(ctx)
  return "pass" -- do not scan the connection
end

2.Dr.Web Firewall for Linuxに対し、drwebグループのユーザー権限で実行されているアプリケーションからの送信ローカル接続、または(接続の所有者とその方向に関係なく)権限のあるポートから開始された接続、またはローカルネットワークからのIPアドレスから始まる接続を除く、確立された接続すべてをスキャンのために送信するように指示するスクリプト。

function intercept_hook(ctx)
  -- Do not scan connections, initiated from the local
  -- host (divert == "output") by application under the name of
  -- "drweb" (group == "[drweb]")
  if ctx.divert == "output" and ctx.group == "drweb" then
    return "pass"
  end

  -- Do not scan connections, initiated from
  -- privileged ports (range is from 0 to 1024)
  if ctx.src.port >= 0 and ctx.src.port <= 1024 then
    return "pass"
  end

  -- Do not scan connections from local network IP addresses
  -- (IP address range 127.0.0.1/8)
  if ctx.src.ip.belongs("127.0.0.0/8") then
    return "pass"
  end

  -- 接続はデフォルトでスキャンされます
  return "check"
end

使用中のテーブル

1.InterceptContextテーブル

このテーブルは、処理された接続のデータをintercept_hook関数に転送するために使用されます。データを使用して、接続をどうするかを決定できます(スキャンせずにスキップ、切断、またはSpIDer Gateによるスキャンのために送信)。Dr.Web Firewall for Linuxではテーブルにデータを入力します。テーブルのデータの中には、intercept_hook関数が実行される時点ですでに認識されているものがあります。他の情報(いわゆる「遅延」データ)は、テーブルの該当するフィールドのリクエストに応じて直接評価されます。テーブルには以下のフィールドを含みます。

フィールド

説明

データタイプ

src

接続を開始したクライアントのアドレスとポート

例:

if ctx.src.port >= 0 and ctx.src.port <= 1024 then
  return "pass"
end

TcpEndpointテーブル

dst

クライアントによって接続が開始されたサーバーのアドレスとポート

例:

if ctx.dst.ip.belongs("10.20.30.41/8") then
  return "reject"
end

TcpEndpointテーブル

divert

監視した接続のタイプ。以下のいずれかの値にできます。

「output」 - 送信接続。

「input」 - 受信接続。

「forward」 - トランジット接続。

例:

if ctx.divert == "forward" then
  return "check"
end

文字列

iface_in

接続元のインターフェース名。

インターフェース名が定義されていない場合は、nil値になります。

文字列

iface_out

接続を初期化するパケットが送信されたインターフェース名。

インターフェース名が定義されていない場合は、nil値になります。

文字列

uid

送信接続を開始したユーザーID。

接続タイプ(divert)が「output」ではない場合、またはUIDを定義できない場合は、nil値になります。

番号

gid

送信接続を開始したグループID。

接続タイプ(divert)が「output」ではない場合、またはGIDを定義できない場合は、nil値になります。

番号

user

送信接続を開始したユーザー名。

接続タイプ(divert)が「output」ではない場合、またはユーザー名を定義できない場合は、nil値になります。

文字列

group

送信接続を開始したグループ名。

接続タイプ(divert)が「output」ではない場合、またはユーザー名を定義できない場合は、nil値になります。

文字列

pid

送信接続を開始したプロセスID。

接続タイプ(divert)が「output」ではない場合、またはPIDを定義できない場合は、nil値になります。

番号

exe_path

送信接続を開始したアプリケーションの実行可能ファイルへのパス。

接続タイプ(divert)が「output」ではない場合、または実行可能パスを定義できない場合は、nil値になります。

文字列

無効になったメタメソッド:なし

2.TcpEndpointテーブル

このテーブルは、接続ポイント(クライアントまたはサーバー)のアドレスを説明しています。以下のフィールドを含みます。

フィールド

説明

データタイプ

ip

IPアドレス

IpAddressテーブル

port

ポート番号

番号

無効になったメタメソッド:

__tostring - TcpEndpointを文字列に変換する関数。例:「127.0.0.1:443」(IPv4)または「[::1]:80」(IPv6)

__concat - TcpEndpointを文字列に追加する関数

利用可能な補助モジュール

LuaのプログラムスペースでDr.Web for UNIX Internet Gatewaysとやり取りするために、次の特定のモジュールをインポートできます。

モジュール名

機能

Luaプログラムを起動したDr.Web for UNIX Internet GatewaysコンポーネントとLuaプロシージャの非同期実行の手段のログに、Luaプログラムからのメッセージを記録する機能を提供するモジュール

Dr.Web LookupDモジュールを呼び出して外部ソースからデータを要求するためのツールを提供するモジュール

drwebモジュールの内容

1.機能

このモジュールは次の機能を提供します。

1.1.LuaプログラムからのメッセージをDr.Web for UNIX Internet Gatewaysコンポーネントログに保存するための機能:

log(<level>, <message>)<message>文字列をDr.Web for UNIX Internet Gatewaysログ<level>レベル(必要なレベルは、「debug」「info」「notice」「warning」「error」を使用して定義します)で書き込みます。

debug(<message>)<message>文字列をDr.Web for UNIX Internet GatewaysログDEBUGレベルで書き込みます。

info(<message>)<message>文字列をDr.Web for UNIX Internet GatewaysログINFOレベルで書き込みます。

notice(<message>)<message>文字列をDr.Web for UNIX Internet GatewaysログNOTICEレベルで書き込みます。

warning(<message>)<message>文字列をDr.Web for UNIX Internet GatewaysログWARNINGレベルで書き込みます。

error(<message>)<message>文字列をDr.Web for UNIX Internet GatewaysログERRORレベルで書き込みます。

1.2.Luaプロシジャの同期管理のための機能:

sleep(<sec.>)はこのLuaプロシジャインスタンスの実行を指定された秒数で一時停止します。

async(<Lua function>[, <argument list>])は、指定された関数の非同期開始を起動し、指定された引数リストに転送します。async関数呼び出しはすぐに完了し、戻り値(Futureテーブル)を使用すると、<Lua function>の結果を取得できます(まだ実行が完了していない場合は、完了するまで待機している可能性があります)。

1.3.IPアドレスをIpAddressテーブルとして表示するための機能:

ip(<address>は、IpAddressテーブルの形式で<address>文字列として送信される、IPアドレスを指定します。IPv4またはIPv6アドレスのいずれかを使用できます。

1.4.テキストファイルから外部データをアップロードするには:

load_set(<file path>は、指定されたテキストファイルのコンテンツからtrue値を含むテーブルを生成し、ファイルから読み取られた文字列はキーとして使用されます。空の文字列と空白文字のみで構成される文字列は無視され、テーブルには含まれません。

load_array(<file path>は、指定されたテキストファイルのコンテンツから文字列の配列を生成します。空の文字列と空白文字のみで構成される文字列は無視され、配列には含まれません。

2.テーブル

2.1.Futureテーブルは、async関数を使用して関数を実行した後の保留中の結果を表します。テーブルには以下のフィールドを含みます。

フィールド

説明

データタイプ

wait

async関数を使用して開始した関数の結果を返す関数。関数がまだ実行を完了していない場合は、完了を待って結果を返します。waitが呼び出される前に関数が完了した場合、結果はすぐに返されます。開始された関数が失敗した場合、wait呼び出しは同じエラーを生成します。

機能

無効になったメタメソッドなし

2.2 IpAddressテーブルはIPアドレスを表します。以下のフィールドを含みます。

フィールド

説明

データタイプ

belongs

指定したサブネット(IPアドレス範囲)のIpAddressテーブルに保存されているIPアドレスの所属を確認する関数。

<IP address>または<IP address>/<mask>のような文字列を唯一の引数として受け取ります。ここで、<IP address>はホストアドレスまたはネットワークアドレス(「127.0.0.1」など)、<mask>はサブネットワークマスク(「255.0.0.0」などのIPアドレスとして、または「8」などの数値形式で指定できます)です。

ブール値を返します。

trueは、アドレスが指定されたアドレスの少なくとも1つと等しいか、指定されたサブネット(IPアドレスの範囲)の少なくとも1つに属していることを示します。

false - それ以外の場合。

機能

無効になったメタメソッド:

__tostringは、文字列内のIpAddressを変更する関数です。例:「127.0.0.1」(IPv4)または「::1」(IPv6)

__concatは、IpAddressを文字列に結合する関数です。

__eqは、2つのIpAddressが等しいことを確認するための関数です。

__bandは、マスクを適用するための関数(例:dw.ip('192.168.1.2') & dw.ip('255.255.254.0'))です

3.例

3.1.非同期的に開始される手順によって生成される、ログへの出力メッセージ:

local dw = require "drweb"

-- この関数は2秒間待機して文字列を返します。
-- 引数として受信されます
function out_msg(message)
 dw.sleep(2)
 return message
end

-- 「メイン」関数
function intercept(ctx)
 -- NOTICEレベルでDr.Web for UNIX Internet Gatewaysログに文字列を出力します
 dw.notice("Intercept function started.")

 -- out_msg関数の2つのコピーを非同期で起動します
 local f1 = dw.async(out_msg, "Hello,")
 local f2 = dw.async(out_msg, " world!")

 -- out_msg関数のコピーの完了を待機中です
 -- out_msgとその結果をログに出力します
 -- Dr.Web for UNIX Internet Gateways ログにデバッグレベルで出力します
 dw.log("debug", f1.wait() .. f2.wait())
end

3.2.指定されたスケジュールに従って定期的に開始する手順を作成する:

local dw = require "drweb"

-- Futureテーブルをfutureグローバル変数で保存し、
-- Luaのガベージコレクターにより
-- 計画されたタスクが破壊されないようにします
future = dw.async(function()
  while true do
     -- 毎日、次のメッセージがログに表示されます
     dw.sleep(60 * 60 * 24)
     dw.notice("A brand new day began")
  end
end)

3.3.文字列のIPアドレスを変更する:

local dw = require "drweb"

local ipv4 = dw.ip("127.0.0.1")
local ipv6 = dw.ip("::1")
local mapped = dw.ip("::ffff:127.0.0.1")

drweb.lookupモジュールの内容

1.機能

このモジュールは次の機能を提供します。

lookup(<request>, <parameters>)はDr.Web LookupDモジュールから利用できる外部ストレージからデータを要求します。<request>パラメータは、Dr.Web LookupD設定内のセクション(文字列<type>@<tag>)に対応している必要があります。<parameters>引数はオプションで、リクエストを生成するために使用される置換を表します。これらのパラメータはテーブルとして設定されます。このテーブルのキーと値は文字列でなければなりません。この関数は、リクエストの結果である文字列の配列を返します。

check(<checked string><request><parameters>は、Dr.Web LookupDモジュールを介して利用できる外部リポジトリで<checked string>が見つかった場合にtrueを返します。引数<request>および<parameters>は、lookup関数の引数と同じです(上記を参照)。<checked string>引数は、文字列または__tostringメタメソッドを持つテーブル(つまり、文字列にフォーマットできる)であると想定されます。

2.例

データソースLookupD.LDAP.usersから取得されたユーザーリストのログへの出力:

local dw = require "drweb"
local dwl = require "drweb.lookup"

-- 「メイン」関数
function intercept(ctx)
 -- NOTICEレベルでDr.Web for UNIX Internet Gatewaysログに文字列を出力します
 dw.notice("Intercept function started.")

 -- リクエスト結果をDr.Web for UNIX Internet Gatewaysログへ出力
 -- 'ldap@users’データソースへ
 for _, s in ipairs(dwl.lookup("ldap@users", {user="username"})) do
   dw.notice("Result for request to 'ldap@users': " .. s)
 end

end