2009年9月27日日曜日

Proxyソフト Delegateの設定

Delegateは国産の、しかもフリーのProxyソフトです。
電子技術総合研究所の佐藤豊さんが作成しています。
UNIX、Linix、Windows、MacOS等の主要OSに対応しています。
本家サイトは、http://www.delegate.org/です。

対応しているプロトコルもHTTPはもちろん、FTP、SMTP、POPも対応しています。
TCPやUDPの第4層のプロトコルを処理してくれるためソフトウェアルーターのように動作してくれるため柔軟なネットワーク設定に対応します。

国産ですが英語サイトのみしかなく、マニュアルもスイッチの説明が主なため設定のハードルはすこし高めです。

ここではWindows版のDelegateで、HTTP、HTTPS、FTP、SMTP、POPの設定を説明します。

Delegate導入の動機と目的は、本社を中心に拠点をVPNでつないだ環境があり、インターネットへは本社ルーターを経由する必要がありますが、ルーターには拠点からインターネットに接続するルーティングテーブルの設定がありません。拠点のクライアントは本社ネットワークまでは接続できるのでDelegateを導入することでインターネット上のWeb、FTP、メールのサービスを代行してもらいます。もちろん最善解はルーターにルーティングテーブルを設定すればよいのですが事情によりルーターの設定変更ができないためDelegateを導入します。

では実際の設定手順です。概要はつぎのとおりです。


  1. 本家サイトよりDelegateをダウンロード
  2. ダウンロードしたファイルの解凍と配置
  3. cfgファイルの作成
  4. Delegateの起動とサービス登録

1、Delegateのダウンロード

本家サイトよりWindows版のファイルをダウンロードします。現時点での最新バージョンは、9.9.4でダウンロードファイルは、dg9_9_4.zipでした。http://www.delegate.org/anonftp/DeleGate/bin/windows/latest/dg9_9_4.zip


2、ダウンロードしたファイルの解凍と配置

ダウンロードしたファイルを解凍します。
解答したファイルは”dg_9_9_4”のようなフォルダ名になります。
解凍したフォルダをPlogram Filesに配置します。(実際は任意の位置で動作します)

3、cfgファイルの作成
cfgファイルはDelegateを起動する際のスイッチをファイルにまとめて保存したものです。
今回は、HTTP、HTTPS、FTP用とSMTP用、POP用のcfgファイルを作成します。
また、SMTP用は一般的な25番ポートを利用するものと、Outbound Port 25 Blockingに対応するための587番ポートを利用するもので2つcfgファイルを作成して全部で4つのcfgファイルを作成します。

http.cfg
-P=80
SERVER=http
MANAGER=http@mail.com

smtp.cfg
-P=25
SERVER=smtp://smtpサーバーアドレス/
MANAGER=smtp@mail.com

smtp587.cfg
-P=587
SERVER=smtp://smtpサーバーアドレス:587/
MANAGER=smtp@mail.com

pop.cfg
-P=110
SERVER=pop://popサーバーアドレス/
MANAGER=pop@mail.com

以上の4つのcfgファイルを作成し、Delegate本体と同じ場所に保存します。

各cfgファイルとも3行しかありません。
-PはProxyで利用するポート番号です。
SERVERはDelegateのサポートするプロトコルです。
MANAGERは管理者のメールアドレスです。ダミーでOKですが無いと起動できません。

Delegateの導入の動機からするとログの取得等は必要がないためシンプルになっています。
SERVERオプションでは、smtpとpopはサーバーのアドレスが必要です。
HTTPSとFTPはDelegateをデフォルトで起動すると同時に起動するため特に設定がありません。

4、Delegateの起動とサービス登録
Delegateはサービスとして起動します。テスト時はコマンドプロンプトで対話起動することもできます。
また、HTTP用、SMTP用、POP用とで別々のプロセスで動作するようになっています。
Delegateの起動はコマンドプロンプトでつぎのように入力します。
dg9_9_4.exe –P80 +=http.cfg
サービスに登録するかを聞かれますので”y”を入力してEnterで確定します。



残りの3つのcfgファイルも同様に設定します。

管理ツールよりサービスで起動していることが確認できます。



設定は以上で終了です。

2009年6月26日金曜日

RRASとIPSecの考察

Windows XPでVPNといえばPPTPがもっともメジャーな存在です。

安価なブロードバンドルーターにもPPTPサーバーの機能が備わっている製品もあるため、簡単、低コストでVPNが構築できます。



PPTPの弱点は認証をユーザーアカウントとパスワードのみに頼っているため、もしもアカウントとパスワードが漏れてしまえば、すぐにVPNに侵入されてしまうことです。

実体験から言えば退職者のアカウントが放置されて、退職後もひそかにLANに侵入することができます。



PPTP自体はきちんとした暗号化も備えているため、何もしらない第3者がLANに接続することはまれです。しかし、どのクライアントに接続設定がされているか確認するのは困難ですし、アカウントとパスワードさえ分かっていれば、WindowsXP端末なら簡単に接続を作成できるため、いつ、誰がアクセスしているかをコントロールできずに安全性がきわめて低くなることが予想されます。



PPTPに代わるソリューションで、まず考えられることはFortiGateやNetScreenなどのファイヤーウォール系のソリューションです。

これらのソリューションは堅牢です。しかし、設定すらままならないこともあります。正規のアカウントやパスワードがあっても接続設定自体が不透明で困難です。また、専用のクライアントソフトを必要とすることがほとんどで、新しいOSが登場してもなかなかクライアントソフトは登場せず、端末のリプレースを困難にすることも少なくありません。

RRASはPPTPの他に標準でL2TP/IPSecも対応していますので、こちらの利用を検討します。
ちなみに、ここのところ実装している事前共有キーでのL2TP/IPSecの認証は、アカウント+パスワード+事前共有キーで、結局のところPPTPとあまり変わりません。
事前共有キーは1つしか設定できないため、もしも変更する場合はクライアントすべてを変えなくてはなりません。管理者自身ですべて変更できなければ、通知して変えてもらうしかありませんが、これでは意味がありません。
Windowsのアカウントは有効、無効が管理者で簡単に制御できますし、アカウントロックの機能もポリシーで細かく制御できるため、こちらの方が気が利いています。しかし、Windowsアカウントはパスワードが生年月日になっていたり、部署内でパスワードをお互いに知っていたりすることは普通なことです。これでは、リモートアクセスを許可されている人のアカウントで簡単にLANに侵入されます。

Windows2003ServerはCAとしての機能も備えているため証明書を利用することがベストと思われます。設定については今後確認していきますが、以前設定した際にはかなり簡単だったと記憶しています。証明書であれば、管理者でなくては発行できないため漏洩の可能性はかなり低くなります。また、リモートアクセスが許可されたユーザーであっても証明書がインストールされていなければ接続できないため、自宅のPCに勝手に設定することも防ぐことができます。この時点で管理者はリモート接続のユーザーと端末を管理できます。また、接続を不許可にしたい場合は証明書を失効させることで不許可にできます。

RRASはWindowsServer上のソフトウェアルーターのためスループットは専用ルーターに比べて見劣りするものです。ただし、モバイル端末の運用が一般的になってきた昨今では端末の接続管理のための機能が充実しているため導入の価値があります。
ゲートウェイ製品を利用したアカウント管理は概ね英語のインターフェースか元々英語だったインターフェースを日本語にしただけのものが多く遣いづらいものが少なくありません。WindowsServerはこの点でもアドバンテージがあります。

IPSecは固定IPでなくてはいけないとか、証明書は高価だという過去の知識でIPSecの導入を見送ることはもったいないといえます。

2009年6月25日木曜日

リモートデスクトップ、ターミナルサービスでプリンタがマウントされない

あるユーザーでは2003Serverのターミナルサービスを利用して業務を行っています。ターミナルサービスは遠隔地のサーバーの画面を透過的に見るため、データは一括してサーバーに保管されますし、データの実行環境(このユーザーはMicrosoft Access)もクライアントPCに左右されなくなるのでメリットがあります。遠隔地のサーバーの画面を見ているとはいえ印刷はクライアントのある場所でないと不便になります。もちろんこの点についてはきちんと考えられていて、クライアントのプリンタをサーバー経由でリダイレクトして印刷ができるようになっています。

PCの入れ替えやコピー、印刷機の入れ替えの際は、プリンタがリダイレクトされるように設定する必要がありますが、基本的にはリモートデスクトップ接続を作成するときにプリンタをリダイレクトする項目にチェックを入れるだけでOKになります。
ところが、この設定をしていてもプリンタが表示されない現象にあたるケースが2回ほど続いたため調べたところ、つぎのような情報がありました。

2003ServerにリダイレクトするプリンタのポートがLPT、COM、USBのいずれでもない場合リダイレクトされません。

この情報を鵜呑みにすると、リダイレクトできるプリンタはセントロ、RS-232C、USBでクライアントPCに接続されていなくてはいけないことになります。昨今のプリンタはLANで接続が当たり前なのでこれでは使い物になりません。

もちろん実際にはLAN接続のプリンタも使えるのですが、リモートデスクトップのプリンタのリダイレクトをチェックしてもマウントされない場合はレジストリより設定を変更します。以下のURLを参考に変更することでリダイレクトされるようになります。
http://support.microsoft.com/kb/302361/ja
ユーザーのPCにてレジストリを変更する場合は十分な注意が必要です。

2009年6月23日火曜日

Excelで1文字目が勝手に確定する



Excelで文字入力中に1文字目が勝手に確定してしまう症状が発生することがあります。


例えば「佐藤」と入力すべきところが「sあ藤」などとなってしまいます。




特ににExcel2007での報告例が多いようです。




障害復旧の手順としては、Excel.exeを右クリック(ショートカットではない)


Excel2007なら”C:\Program Files\Microsoft Office\Office12”のexcel.exeを右クリックして互換のタブを開いて入力設定の”このプログラムでは詳細なテキストサービスを無効にする”にチェックをすることで回避できるようです。






今のところ実際に確認していません。




また、同様の設定がIMEにもあるらしいのでExcel以外での発生時にはこちらも確認する必要がありそうです。

2009年6月19日金曜日

BackupExecとSQLの照合順序の問題点

Symantec Backup ExecのSQL対応版をインストールする際に発生したトラブルを1つ

SQL Serverは大塚商会のSumileのために稼動しており、これをBackupExecでバックアップするように設定しようとしたところ次のようなトラブルが発生しました。

BackupExecインストール後、同ソフトを起動しようとするとメディアサーバーへの接続が表示されてアカウントとパスワードを入力するように求められます。
アカウントとパスワードを入力すると、「メディアサーバーに接続できませんでした。」とエラーになってしまう状況になります。
BackupExecの動作に必要なサービスがダウンしていて、手動で起動しても起動できない状態です。

「Backup Exec Server サービスが起動されていません。 オブジェクト 11 で内部エラー (-536837662) が発生しました。 」 というようなメッセージもでます。


この原因はBackupExecのインストール時にBackupExecが動作するためにSQLサーバー上にデータベースを作ります。このデータベースはBackupExecのインストール時に既存のインスタンスにデータベースを追加するか、専用にインスタンスを作成するかを選ぶことができますが、既存のインスタンスに間借りする場合、そのインスタンスの照合順序がバイナリになっているとこのようなエラーになるようです。

大塚商会のsmileはまさにこの状態でした。

別インスタンスにしたところ正常に動作するようになりました。

2009年6月18日木曜日

YAMAHAルーターのconfigの設定、保存

YAMAHAのルーターの設定情報(config)を保存するためにはTFTPを利用します。

取得
 tftp [router-ip] get config /[administrator password] config.txt

設定
tftp [router-ip] put config.txt config /[administrator password]

設定、取得をするルータは事前にtftpの使用を許可する必要があります。

tftpのアクセスを許可するためには

#tftp host [許可するip]
#save

とします。

接続を許可するipを限定しない場合は
#tftp host any
#save
としておきます。

2009年6月17日水曜日

SQL Server 2000の注意点

古い奉行やPCAのソフトなどでSQL Server 2000を利用しているケースは多いですが、PC入れ替えなどでの再セットアップ時に注意が必要です。

奉行やPCAのインストーラは自動的にSQL Server 2000をインストールしてくれますが、サービスパックをインストールしてくれません。
ソフトの発売当初はサービスパックがなかった可能性があるので仕方ありませんが、いまはSP4を入れないと問題ありです。

一番問題なのは、ネットワークからアクセスできないことです。
正しいアクセス権が付与されていても、アクセスできないためハマる可能性が高くなります。

SQL Seerver 2000でネットワークアクセスできない場合はSP4があたっているかは必ず確認する必要があります。

注意:サービスパックはインスタンス毎にあたるらしいので注意が必要です。

2009年6月16日火曜日

PCA会計の不具合

PCA会計9にて合計残高試算表の出力の際に、集計の開始日と終了日が入力できない障害が発生。
具体的には、開始日は入力できるが終了日が入力できない症状。

原因は不明・・・

障害の復帰はPCA会計9のクライアントの再インストールで復帰!

不思議なこともあるもんだ・・・

2009年5月25日月曜日

DataSetとオブジェクト指向の相性

.Net Frameworkは生産性の高いフレームワークです。ほとんどコーディングをしなくてもバックグラウンドにSQL Server、フロントエンドに.Net Frameworkの本格的なアプリケーションを構築することが可能です。これを支えているのソリューションはおそらくDataSetではないかと思います。ここではDataSetとオブジェクト指向の相性について再考します。

Visual Studioでは開発環境でデータベースへの接続を作成して、その接続からDataSetを作成することができます。さらにDataSetからフォーム上にDataSetと連結したコントロールを配置することができます。この手順には1行のコーディングも必要がありません。

上記の理由から.Net Frameworkは生産性が高いということが言えます。が、落とし穴もじつはあるのでは…と思うわけです。

SQLデータベースをデータストアにしてフロントエンドを開発すると思いがけずオブジェクト指向から外れることがあるように思います。

オブジェクト指向においてクラスは現実のオブジェクトをモデル化する存在といえます。あるモデルを表すためのデータはクラスを中心にして存在するべき存在です。しかし、バックグラウンドにSQLデータベースが存在するとデータはSQLデータベースのテーブルの構造に支配されてしまう感があります。

Visual Studioの開発環境ではフォーム上にいくつかのコントロールが存在して、DataSetにバインドされているアプリケーションが簡単に作成されます。これも有意義なアプリケーションです。しかし、この場合のクラスはフォームであって、フォームにメソッドを作る場合でも現実のオブジェクトを操作する感覚からはかけ離れています。フォームやその上のコントロールのイベントを取得してデータを操作することに終始してしまいます。

これはオブジェクト指向の意図するところではないはずです。

オブジェクト指向は、まず現実のモデル化ありきです。
モデル化に必要なデータはすべてクラスに含めます。そして、実体のあるオブジェクトを操作するかのようにメソッドを実装しなくてはなりません。

DataSetとオブジェクト指向の相性の結論ですが、DataSetはデータの集合です。SQLデータベースのサブセットに相当するのでDataSet=SQLデータベースが存在すると思っても間違いではありません。
DataSetが便利なのは、データの挿入、更新、削除などの操作性の便が図られているからです。もし、SQLデータベースがDataSetと同じ要領で操作できるのならDataSetはそれほど重要ではないかもしれません。

オブジェクト指向のクラスは現実のオブジェクトをモデル化したデータと操作メソッドの集合です。DataSetはデータの集まりですがメソッドを持たせることはできません。DataSetがメソッドを持つことができれば、それも、オブジェクト指向に則することになります。しかし、残念ながらそれはできません。

結局、DataSetはあくまでもSQLデータベースとクラスの仲立ちをするデータベースのサブセットであるということです。

プログラムの実際において実行しなくてはいけないことは、現実のオブジェクトをモデル化したオブジェクトを作成すること。そして、このクラスに必要なデータをDataSetとしてSQLデータベースから切り出して準備して、いちいちクラスにセットすることです。クラスに取り込んだデータは処理後にDataSetにもとした後、更新をかけるという手順を踏むことです。
DataSetのデータをクラスにセットする手順と戻す手順は一度コーディングすれば常に同じ手順なので使いまわしできます。
面倒は増えますがクラスのメソッドの持つ強力さは複雑なソフトで威力を発揮します。
ソフトが複雑になるケースでは、この手間をかけることで全体のコーディングを減らすことができるものと期待できます。

コードの実装はまだしていませんが、今後、実装を試してみたいと思います。

2009年5月23日土曜日

C# 複数フォームから1つのフォームを共有する

C#は.Net Frameworkを含めて生産性の高いツールだと感じます。
ある機能を持った親フォームから子フォームを呼び出して、子フォームのデータを親フォームに返したいことがよくあります。このような場合以下のように実装します。

public partial Class ParentForm : Form
{
    protected string dataFromCoForm;
    private void Button_Click(object sender, EventArgs e)
    {
        ChildForm childForm = new ChildForm(this);
        childForm.Show();
    }
}

public partial Class ChildForm : Form
{
    ParentForm parentForm;
    public ChildForm(ParentForm o)
    {
        parentForm = o;
    }
    public ChildForm_Load()
    {
        parentForm.dataFromCoForm = “親フォームへの文字列”;
    }
}

このコードでは親フォームが子フォームを呼び出す際に自分の参照を渡しています。
子フォームでは受け取った親フォームの参照を親フォーム型のフィールドにコピーしています。
親フォームには子フォームからアクセスできるフィールをがあるため参照を通して親フォームにデータを返すことができます。

ここで他のフォームを作成して同じ子フォームを呼び出そうとすると問題が生じます。
新しく作成したフォームをnewParentFormクラスとした場合、newParentForm型の参照が子フォームに渡されます。子フォームは渡された参照をparentForm型のフィールドへコピーしようとしますが、これは失敗します。(実際にはコンパイル時点でエラーになります)単純に型が違うことが原因です。

子フォームがまったく同じでよいのなら共有するほうが生産性もあがるし、たった1行のために似たような子フォームクラスを作らずに済みます。以下に、このような場合の解決方法を示します。

まず基本的な考え方を説明します。
子フォームを共有する親フォームは、派生元になる中間フォームを作成します。通常親フォームはWindows.Formsクラスから派生しますが、Formsクラスから中間フォームを派生させて、さらに親フォームを派生するように作成します。
中間フォームには子フォームから値を返すフィールドやプロパティ、あるいはメソッドを準備します。
子フォームは親フォームから受け取った参照を中間フォーム型のフィールドにコピーします。親フォームは中間フォームから派生しているためコピーは成功します。
では、以下にコードを示します。

public partial class 中間フォーム : Form
{
    public 中間フォーム()
    {
        InitializeComponent();
    }
    public virtual void SetValue()
    {
    }
}

public partial class 親フォーム1 : 中間フォーム
{
    public 親フォーム1()
    {
        InitializeComponent();
    }
    private void btnCallChildForm_Click(object sender, EventArgs e)
    {
        子フォーム CoForm = new 子フォーム(this);
        CoForm.Show();
    }
    public override void SetValue(string s)
    {
        MessageBox.Show("親フォーム1");
        this.textBox.Text = s;
    }
}

public partial class 親フォーム2 : 中間フォーム
{
    public 親フォーム2()
    {
        InitializeComponent();
    }
    private void btnCallChildForm_Click(object sender, EventArgs e)
    {
        子フォーム CoForm = new 子フォーム(this);
        CoForm.Show();
    }
    public override void SetValue(string s)
    {
        MessageBox.show("親フォーム2");
        this.textBox.Text = s;
    }
}

public partial class 子フォーム : Form
{
    object Obj;
    public 子フォーム()
    {
        InitializeComponent();
    }
    public 子フォーム(object o)
    {
        InitializeComponent();
        Obj = o;
    }
    private void btnReturn_Click(object sender, EventArgs e)
    {
        中間フォーム superForm = (中間フォーム)Obj;
        superForm.SetValue("この値は子フォームからの値です。");
        this.Close();
    }
}

コードは以上です。
2つのフォームから共通のフォームを共有することができています。
中間フォームにはテキストボックスに値をセットするためのメソッドが準備してあります。このメソッドはvirtualメソッドになっていて、2つの親フォームでoverrideしています。中間フォームのメソッドを仮想メソッドにすることで呼び出し元の親フォームのメソッドが実行されるようになります。

この方法で1つのフォームを共有できますが注意点があります。
子フォームはsetValueメソッドで親フォームへデータを返すため、新しく作成する親フォームはsetValueメソッドをオーバーライドする必要があります。
また、今回メソッドで値を親フォームにセットしていますが、これはTextBoxへ値をセットするための手法です。もし、フィールドにデータをセットした場合、親フォームでTextBoxに値をコピーしなくてはならないためメソッドで値をセットしました。

ある程度規模の大きいソフトを作ろうと考えているなら、始から中間フォームを準備しておいたほうがよいかもしれません。