web-dev-qa-db-ja.com

Linux NFLOG-ドキュメント、Cからの構成

いくつかの異なる場所(例 http://wiki.wireshark.org/CaptureSetup/NFLOG )では、次のように、Linuxの「NFLOG」ファイアウォールモジュールを使用して、特定のUIDによって生成されたパケットをキャプチャすることを推奨しています。

# iptables -A OUTPUT -m owner --uid-owner 1000 -j CONNMARK --set-mark 1
# iptables -A INPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# iptables -A OUTPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# dumpcap -i nflog:30 -w uid-1000.pcap

これが正確に機能するためのドキュメントを見つけることができませんでした(特に、 netfilter.org は、十分に記述されていないライブラリAPIドキュメントがたくさんあり、私が知る限り、実際のカーネルレベルのファイアウォールルールのセマンティクスについては何もないため、いくつか質問があります。

  1. Isいまいましいドキュメントはどこにあり、どこに隠れていますか?

  2. CONNMARKのものが実際に必要ですか?つまり、これも同様に機能しますか?

    # iptables -A INPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30 
    # iptables -A OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30
    
  3. これを機能させるには、「ulogd」を実行する必要がありますか?

  4. カーネルに割り当てられていないグループ番号を選択してそれを教えてくれる方法はありますか?

  5. プロセスXが終了すると、これらのフィルター規則が自動的に削除されることをカーネルに伝える方法はありますか? (プロセスXはnotがuid 1000として実行されます。)

  6. おそらくiptablesコマンドは、いくつかの特別なioctl呼び出しまたはファイアウォールを構成するための何かを行います。プログラム内から同じことを行うために使用できるCライブラリ(つまり、Q4の「プロセスX」)はありますか?

5
zwol

いまいましいドキュメントはありますか?それはどこに隠れていますか?

機能の説明に役立つnetfilterサイトの例があります。これが、netfilter NFLOGを設定する、自分のコードで記述した関数です。

それらが提供する例を以下に示します。 http://www.netfilter.org/projects/libnetfilter_log/doxygen/files.html

void setup_netlogger_loop(
    int groupnum,
    queue_t queue)
{
  int sz;
  int fd = -1;
  char buf[BUFSZ];
  /* Setup handle */
  struct nflog_handle *handle = NULL;
  struct nflog_g_handle *group = NULL;

  memset(buf, 0, sizeof(buf));

  /* This opens the relevent netlink socket of the relevent type */
  if ((handle = nflog_open()) == NULL){
    sd_journal_perror("Could not get netlink handle");
    exit(EX_OSERR);
  }

  /* We tell the kernel that we want ipv4 tables not ipv6 */
  if (nflog_bind_pf(handle, AF_INET) < 0) {
    sd_journal_perror("Could not bind netlink handle");
    exit(EX_OSERR);
  }

  /* Setup groups, this binds to the group specified */
  if ((group = nflog_bind_group(handle, groupnum)) == NULL) {
    sd_journal_perror("Could not bind to group");
    exit(EX_OSERR);
  }
  if (nflog_set_mode(group, NFULNL_COPY_PACKET, 0xffff) < 0) {
    sd_journal_perror("Could not set group mode");
    exit(EX_OSERR);
  }
  if (nflog_set_nlbufsiz(group, BUFSZ) < 0) {
    sd_journal_perror("Could not set group buffer size");
    exit(EX_OSERR);
  }
  if (nflog_set_timeout(group, 1500) < 0) {
    sd_journal_perror("Could not set the group timeout");
  }

  /* Register the callback */
  nflog_callback_register(group, &queue_Push, (void *)queue);

  /* Get the actual FD for the netlogger entry */
  fd = nflog_fd(handle);

  /* We continually read from the loop and Push the contents into
     nflog_handle_packet (which seperates one entry from the other),
     which will eventually invoke our callback (queue_Push) */    
  for (;;) {
    sz = recv(fd, buf, BUFSZ, 0);
    if (sz < 0 && errno == EINTR)
      continue;
    else if (sz < 0)
      break;

    nflog_handle_packet(handle, buf, sz);
  }
}

CONNMARKのものが実際に必要ですか?つまり、これも同様に機能しますか?

不要です。

これを機能させるには、「ulogd」を実行する必要がありますか?

いいえ。実際、このアプリケーションでは使用しません。

カーネルに割り当てられていないグループ番号を選択してそれを教えてくれる方法はありますか?

私が知っていることではありません。いずれの場合も、HTTPのNFLOGターゲットを設定していて、1つはFTPでドロップされたパケットをログに記録し、もう1つはSMTP文字列をスキャンしていた場合、これは役に立ちません。このシナリオでは、どのルールがどのグループにバインドされているか、したがってどのグループをリッスンするかを決定できません。

プロセスXが終了すると、これらのフィルター規則が自動的に削除されることをカーネルに伝える方法はありますか? (プロセスXはuid 1000として実行されていません。)

いいえ、ただし、カーネルは最大サイズまでのバッファーをいっぱいにしてから、データを破棄します。ルールがリッスンされていないため、メモリを使いすぎてパフォーマンスに影響を与えることはありません。

おそらくiptablesコマンドは、ファイアウォールを構成するために、特別なioctl呼び出しなどを行います。プログラム内から同じことを行うために使用できるCライブラリ(つまり、Q4の「プロセスX」)はありますか?

ルールの操作に役立つ、私が知っているnetfilterライブラリはありません。代わりに使用される内部駆動ライブラリがあります。

IPtablesは、ユーザースペースと話すというかなり古風な方法を継承しています-SOCK_RAW IPソケットを開いて通信します。同じことをするためにnetlinkを介して話すnftablesでこれは完全に削除されます(意味がありません)。

5
Matthew Ife

具体的にこの部分に答える:

CONNMARKのものが実際に必要ですか?つまり、これも同様に機能しますか?

# iptables -A INPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30 
# iptables -A OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30

はい、それは必要です。いいえ、提案は着信パケットと一致しません(おそらくローカルマシンのトラフィックと一致しますが、外部ネットワークトラフィックとは一致しません)。

ローカルの発信パケットのみに関連付けられた所有者があります。 INPUTチェーンの早い段階では、パケットがまだルーティングされているため、所有者情報は利用できません。発信フローに関連する着信パケットを照合するために、その後INPUTチェーンで照合できるOUTPUTチェーンの「接続」にマークを付ける必要があります。

iptables-extensionsのマニュアルページもご覧ください。

オーナー

ownerモジュールは、元のソケットのみに一致します。つまり

このモジュールは、ローカルで生成されたパケットについて、パケット作成者のさまざまな特性を照合しようとします。この一致は、OUTPUTチェーンとPOSTROUTINGチェーンでのみ有効です。転送されたパケットには、関連付けられたソケットがありません。カーネルスレッドからのパケットにはソケットがありますが、通常は所有者がいません。

(nftablesにも同じ警告が適用されます。)

0
Lekensteyn