技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

リバースプロキシ

普通のプロキシとリバースプロキシとの違いについて簡単にまとめる。

一般的に普通のプロキシは、社内からインターネットに出るところに置いて、社員のインターネットへのアクセスを管理したり、アクセス速度向上のためインターネットから取得したコンテンツをキャッシュしたりする。

一方で、リバースプロキシは、インターネット上に公開しているwebサーバの手前に置いて、インターネットからのアクセスのロードバランスやセキュリティチェックなどを行う。

普通のプロキシが「内部⇒外部」の向きであるのに対して、リバースプロキシは「外部⇒内部」という感じで向きが逆なので、「リバース」という名前が付いているのだと思われる。

 

以下のサイトの説明がとても分かりやすかった。

プロキシサーバとリバースプロキシサーバの違い |

 

 

Linuxへの公開鍵のimport

Linux上にrpmパッケージをインストールする際、そのrpmパッケージに電子署名が付与されている場合は、(署名に使われた秘密鍵に対応する) 公開鍵をLinux上にインストールしておくことが必要となる。

その際の方法として、rpm --import コマンドを使用するのと、gpg --import コマンドを使用するものがあるようだ。ネットで調べても、この二つのコマンドの使い分けは分からなかったのだが、

Chapter 4. Importing Custom GPG Keys - Red Hat Customer Portal

によると、Linuxのバージョンによって使い分けるものだと思われる。また、rpm --import を使う方が新しい方法のように読める。

SNMPのOIDのルール

rfc2578 によると、SNMPのOIDには以下の規定がある。

  • サブID(※)は正数
  • サブIDの個数は128個まで
  • サブIDの最大値は 2^32-1 (4294967295)
  • 少なくても2個のサブIDを持つ
  • 最初のサブIDは 0 or 1 or 2

(※)サブIDとは、OIDを構成する各数値のこと。

 

An OBJECT IDENTIFIER value is an ordered list of non-negative
numbers. For the SMIv2, each number in the list is referred to as a
sub-identifier, there are at most 128 sub-identifiers in a value, and
each sub-identifier has a maximum value of 2^32-1 (4294967295
decimal).

All OBJECT IDENTIFIER values have at least two sub-identifiers, where
the value of the first sub-identifier is one of the following well-
known names:

Value Name
  0 ccitt
  1 iso
  2 joint-iso-ccitt

(Note that this SMI does not recognize "new" well-known names, e.g.,
as defined when the CCITT became the ITU.)

RFC 2578 - Structure of Management Information Version 2 (SMIv2)

の「3.5. OBJECT IDENTIFIER values」より抜粋。

OIDのBER形式でのエンコード

以前、以下の記事のコードを書いた時、SNMPのOIDの BER(Basic Encoding Rule)形式でのエンコード処理について勉強した。

akrad.hatenablog.com

今回は、その時に勉強した内容を書く。

 

SNMPのOIDのエンコードで面倒なのは、OIDの数値が128以上の場合である。というのは、OIDの数値が128以上の場合、1バイトではなく複数バイトで表現することになっており、それら複数バイトの最後の1バイト以外は先頭bitを立てる必要があるからである。文章だけでは分かりにくいと思うので、例を挙げて説明する。

例えば、OIDの中に 9999 という数値があったとする。まず、128 進数として分解すると以下になる。

9999 = (128^1 * 78) + (128^0 * 15

 

エンコードする際、最後の1バイト以外は先頭ビットを立てるので、以下にようになる。(見やすくするために変換結果は16進で表現している。)

78 = 0100 1110‬--(先頭bitを立てる)--> 1100 1110 = 0xCE
15 = 0x0F

以上により、9999 のエンコード結果は CE0F となる。

複数バイトに分けた際、どこまでが一纏まりなのか判別するために上記の仕様になっていると考えている。

 

また、OIDの先頭部分は、「最初のOIDの数値×40 + 二つ目のOIDの数値」として1バイトに纏めることになっているので、例えば、OIDの先頭が .1.3 だったら、1×40+3=43 となり、16進では 2B となる。最初の数値と二つ目の数値についてこうした変換をしている理由は分かっていないが、おそらく1バイトに纏めて通信量を減らすためだと思われる。

 

以上を踏まえると、例えば、「.1.3.6.1.4.1.9999」というOIDをBER形式でエンコードすると、 「2B 06 01 04 01 CE 0F」となる。

16進のSNMP OIDを通常の文字列の形式に変換する

主題の処理を行うperlスクリプト convertOidHexToStr.pl を作成した。使い方は、例えば、「perl convertOidHexToStr.pl 2b06010401CE0F」 や 「perl convertOidHexToStr.pl "2b 06 01 04 01 CE 0F"」 のように指定すると、結果として、人に優しい形式でOID文字列を「.1.3.6.1.4.1.9999」と出力する。

use strict;
use warnings;

# -----------------------
# Check args.
# -----------------------
my $oidHex = $ARGV[0];
$oidHex =~ s/\s//g;
if (length($oidHex)%2 != 0 or $oidHex =~ /[^0-9a-fA-F]/) {
    die "Input is not hex string\n";
}

my @hexUnits = $oidHex =~ /.{2}/g;
my $length = @hexUnits;

# -----------------------
# Main.
# -----------------------
my $oidStr;
my @tmpsubIds;
my $isInMultiBytes = 0;
my $subIdCnt = 0;
for(my $i=0; $i<$length; $i++) {
    my $subId = hex($hexUnits[$i]);
    if ($i == 0) {
        my $firstSubId = int($subId / 40);
        my $secondSubId = $subId % 40;
        if ($firstSubId > 2) {
            die "The first sub id is 0 or 1 or 2.\n";
        }
        $oidStr .= "\." . $firstSubId . "\." . $secondSubId;
        $subIdCnt += 2;
        next;
    }
    
    if ($subId >= 128) {
        $subId -= 128;
        push(@tmpsubIds, $subId);
        $isInMultiBytes = 1;
    }
    elsif ($isInMultiBytes == 1) {
        push(@tmpsubIds, $subId);
        my $subIdForMultiBytes = computeSubIdForMultiBytes(@tmpsubIds);
        $subIdCnt++;
        if (isSubIdCntOverMax($subIdCnt)) {
            die "Sub id count is over the max value(128).\n";
        }
        $oidStr .= "\." . $subIdForMultiBytes;
        @tmpsubIds = ();
        $isInMultiBytes = 0;
    }
    else {
        if (isSubIdOverMax($subId)) {
            die "Sub id is over the max value(4294967295).\n";
        }
        $subIdCnt++;
        if (isSubIdCntOverMax($subIdCnt)) {
            die "Sub id count is over the max value(128).\n";
        }
        $oidStr .= "\." . $subId;
    }
}

print $oidStr;

# -----------------------
# Sub functions.
# -----------------------
sub isSubIdCntOverMax {
    my $subIdCnt = shift;
    if ($subIdCnt > 128) { # According to rfc2578.
        return 1;
    }
    return 0;
}

sub isSubIdOverMax {
    my $subId = shift;
    if ($subId > 4294967295) { # over 2^32-1. According to rfc2578.
        return 1;
    }
    return 0;
}

sub computeSubIdForMultiBytes {
    my @subIds = @_;
    my $length = @subIds;
    my $computedSubId;
    for(my $i=0; $i<$length; $i++) {
        $computedSubId += (128**($length-$i-1)) * $subIds[$i];
    }
    return $computedSubId;
}


パケットダンプを読むとき、
akrad.hatenablog.com
で書いたようにちょっと面倒なところがあるので、このスクリプトを作成した。

ダイレクトブロードキャスト

今日、ダイレクトブロードキャストなるものを初めて知った。ブロードキャストというと、同一ネットワーク内に一斉送信されるものという認識であったが、このダイレクトブロードキャストは異なるネットワーク内に対して一斉送信されるものである。

 

あまり使用されないが、ネットワーク越しにコンピュータの電源を入れる「Wake-on-LAN」で使われることがあるらしい。Wake-on-LAN の概要は以下。

Wake-on-LAN - Wikipedia

 

なお、ダイレクトブロードキャストは、セキュリティ上の理由から、通常はルータでドロップされる設定になっているようだ。

サマータイムで影響を受けるシステム

最近、東京五輪に関連して話題に挙がっているサマータイムの導入。「システムが影響を受ける!」という声が多方面から挙がっているが、システムが影響を受けるケースについて、ネット上の情報をもとに簡単に纏めてみた。

 

  • WindowsLinux等のOSは、内部時間をUTC(世界標準時)で持っていて、その値はタイムゾーンによって変わらない。(OSの時刻表示は、上記の内部時間をタイムゾーンに合わせて加算/減算して表示しているだけ)
  • サマータイムが適用されても、OSの内部時間は変わらない。OSの内部時間がタイムゾーン:JDT(Japan Daylight Saving Time) に合わせて、OSの「時刻表示」が変わるだけ。
  • なので、OS上のシステムが時刻を内部時刻(UTC)で扱っていれば、サマータイムによる時刻の戻り・進みの影響は受けないと思われる。
  • 一方で、システムが時刻をローカルタイム(=OSの表示時刻)で扱っていると、サマータイムによって時刻が戻ったり飛んだりするので、影響を受ける可能性がある。

 

つまり、システム開発において、時刻を取得する際にOSの内部時間(UTC)で扱うAPIを使っていれば、サマータイムが導入されても影響は受けないのではないか。

ただ、東京五輪までに、全てのシステムについて時刻を扱う処理を見直し、時刻をローカルタイムで扱っている箇所を見つけて改修するのは、巷で言われているようにかなり困難であると思う。。