nomurabbitのブログ

Linux環境構築(CentOS5.11)~その1~

<はじめに>
Linuxの環境構築を行う様を記録していきます。

CentOS6.4を使った『Linuxサーバー構築シリーズ』を約1年間放置しておりますが…、

それはそれとして、今回はCentOS5.11を使った環境構築シリーズです。

CentOSにもたせる役割は特に決めていません。

<作業内容>
まずはOSのインストールを行います。

今回構築するのはCentOS5.11です。

ハードウェアは約10年前のdynabookです。スペックは下記の通り。

  • CPU :CeleronM(1.4GHz)
  • メモリ :256MB
  • HDD :40GB


パーティションの分割はだいたい下記の通り。

  • / :1G
  • /boot :100M
  • /tmp :100M
  • /home :16G
  • /var :10G
  • /usr :5G
  • /usr/local:5G

OSのインストール時に6.4のときにあったような『Minimal』とかの指定はありません。

インストールが必要なソフトウェアは個別に指定する(チェックを入れる)必要があります。

今回このタイミングで必要なソフトウェアはありませんので、

チェックをすべて外してインストールを進め完了します。

<まとめ>
インストール自体は特に問題なく完了すると思います。

実際にログインしみると、いろいろ足りません。

次回以降、環境を整えていきます。

Linuxサーバー構築~その5~

<はじめに>
Linuxサーバー構築シリーズその5です。

今回はperlで書いたCGIをWebサーバーで動かします。


<作業内容>
単にCGIを動かすだけであれば特に変更は必要ないですが、

まずは/etc/httpd/conf/httpd.confの中身を見てみます。

f:id:nomurabbit:20131221172749p:plain

User,Groupにapacheとあります。

そこでOSのユーザーを見てみると、apacheというユーザーが確認できます。

f:id:nomurabbit:20131221173258p:plain

おそらくhttpdでCGIを実行するときは、

このapacheユーザーを使うということだと思います。

また、/etc/httpd/conf/httpd.confにはこのような記述もあります。

f:id:nomurabbit:20131221173419p:plain

ここにOptions ExecCGIと記述があることによって、

/var/www/cgi-binフォルダ内で、CGIの実行が許可されます。

それではCGIを作成します。

test.cgi

#!/usr/bin/perl

print "Content-type: text/html\n\n";
print "Hello world";

ファイルのアクセス権を755とし、

/var/www/cgi-bin/test.cgiとして保存します。

ここでlsコマンドに-Zオプションをつけて、selinuxのラベルを確認しておきます。

f:id:nomurabbit:20131221181859p:plain

あまり詳しくはないのですが、

この、httpd_sys_script_exec_tというラベルがついていないと、

CGIが上手く動かないような気がします。

もし、CGIが動かない原因としてラベルが疑われるようであれば、

chcon unconfined_u:object_r:httpd_sys_script_exec_t:s0 /var/www/cgi-bin/test.cgi

というコマンドでラベルの貼り換えが可能です。

ここまで済めば動作確認です。

test.cgiにブラウザからアクセスしてみます。

f:id:nomurabbit:20131221183159p:plain

無事にCGIにアクセスできました。

<まとめ>
今回の記事まででapachを使って

CGIを動かすことができるようになりました。

前回、今回はhttpを使ったアクセスに限定していましたが、

次回以降mod_sslをインストールして

httpsでアクセスする方法も書いていこうと思います。

Linuxサーバー構築~その4~

<はじめに>
Linuxサーバー構築シリーズその4です。

今回はiptablesの修正を行い、80番ポートでwebサーバーにアクセスできることを確認します。

<作業内容>
まず、iptablesの設定を行います。

iptablesの設定ファイルは、/etc/sysconfig/iptablesです。

中身はこのようになっています。

f:id:nomurabbit:20131214111650p:plain

まずは、この部分

:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

「:INPUT」と書いてある行は、自分宛のパケットについての定義です。

続いて「ACCEPT」とあるので、自分宛のパケットは受け入れるという意味になります。

同様に「:FORWARD」、「:OUTPUT」はそれぞれ、

自分を経由するパケット、自分から発信するパケットとなります。

次に、この部分

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

「-A INPUT」とあるので、自分宛のパケットについての定義です。

「-m state --state ESTABLISHED,RELATED」より、

「過去に接続したもの」や「既存コネクションに関係のあるもの」が該当します。

「-j ACCEPT」は、条件に一致するパケットを許可するという意味です。

さらに、

-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT

1行目はicmpの許可、2行目はループバックの許可を指します。

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

前半の「-A INPUT -m state --state NEW」は

「自分宛のパケットで、新規の接続」を指します。

後半の「-m tcp -p tcp --dport 22」のうち、

「-m tcp --dport 22」はtcpの宛先ポート(今回はINPUTなので自分のポート)

が22番であることを、また「-p tcp」はtcpプロトコルを使用することを指します。

最後に「-j ACCEPT」とあるので、

「自分宛で22番ポートに新規で接続となるパケットを許可する」となります。

-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

最後に、ここまでの条件に一致しなかったパケットを破棄します。

では22番ポートを開く記述にならって80番ポートを開いてみます。

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

編集内容を保存したら、iptablesを再起動して確認します。

<まとめ>
iptablesの設定ファイルを編集し、ポートの解放が確認できました。

次回はhttp.confファイルの編集を行います。

Linuxサーバー構築~その3~

<はじめに>
Linuxサーバー構築シリーズその3です。

Linuxサーバー構築シリーズその2の訂正
・ghcはyumでインストールせずに、ghc7.6.3とhaslkell-platformを
 ソースからインストールします。
httpdをyumでインストールしました。
 configの設定は次回以降で書きます。

<実施内容>
さて、今回はghcとhaskell-platformをインストールします。

haskell-platformにはghcが含まれるようなのですが…

とりあえず、先にインストールを試みます。

// ダウンロード
sudo wget http://www.haskell.org/platform/download/2013.2.0.0/haskell-platform-2013.2.0.0.tar.gz

// チェックサムの確認
sha1sum haskell-platform-2013.2.0.0.tar.gz

// 展開
tar xvzf haskell-platform-2013.2.0.0.tar.gz

と、ここでREADMEの中を見てみると…

f:id:nomurabbit:20131211233312p:plain

どうもghc7.6.3が必要みたいですね。

そこで、ghcのダウンロードサイトを確認すると

最新版(2013年12月11日時点)が7.6.3でしたので、これをインストールします。

// ダウンロード
sudo wget http://www.haskell.org/ghc/dist/7.6.3/ghc-7.6.3-x86_64-unknown-linux.tar.bz2

// 展開
tar xvfj haskell-platform-2013.2.0.0.tar.gz

// .configureの実行
./configure --prefix=/usr/local/haskell/ghc/7.6.3

// インストール
sudo make install

これで、ghcのインストールは無事に完了したはずです。

いざ、haskell-platformのインストール!…と、いきたいことろですが

このままだとgmplibが無えよ!って怒られます。

さらにzlibも無えよ!って怒られます。

ついでにOpenGLのライブラリが無えよ!とも怒られるみたいです。

それらのライブラリをインストールします。

// gmpのインストール
sudo wget https://ftp.gnu.org/gnu/gmp/gmp-5.1.3.tar.bz2

tar xjvf gmp-5.1.3.tar.bz2

./configure

make

make check

sudo make install

// /etc/ld.so.confの編集
>include ld.so.conf.d/*.conf
>
>/usr/lib
>/usr/local/lib

sudo ldconfig

// zlibのインストール
sudo wget http://zlib.net/zlib-1.2.8.tar.gz

tar zxvf zlib-1.2.8.tar.gz

./configure

make

sudo make install

// freeglut-develのインストール
sudo yum -y install freeglut-devel

これでようやくhaskell-platformがインストールできます。

// haskell-platformのインストール
./configure --prefix=/usr/local/haskell/haskell-platform/2013.2.0.0

make 

sudo make install

// cabalのupdateもしておきます
cabal update

<まとめ>
今回でghcが使えるようになりました。

次回はiptablesやApacheのあたりを設定していく予定です。

<参考>
http://takuya71.hatenablog.com/entry/2013/02/04/000022

http://neetmenblog.blog116.fc2.com/blog-entry-9.html

Linuxサーバー構築~その2~

<はじめに>
Linuxサーバー構築シリーズその2です。

前回その1ではOSのインストールやNICの有効化を実施しました。

今回はyumリポジトリの確認とSSH公開鍵の作成、

さらに起動プロセスの確認を行います。


<実施内容>
yumリポジトリの確認

/etc/yum.repo.d/CentOS-Base.repoの内容を編集します。

[base],[updates],[extras],[centosplus],[contlib]の値について

初期値はbaseurlがコメントアウトされているので、

理研のurlに変更してコメントアウトを解除します。

編集内容を保存してyum updateを実施します。

yumのログは/var/log/yum.log に出力されるので中身も確認すると、

先ほどアップデートしたパッケージのログが確認できます。


ssh公開鍵の作成

CentOS 6.4をインストールするとsshが最初からインストールされていて

OS起動時にsshdも起動しています。

また、iptablesを確認すると22番ポートも開いています。

このままでもユーザーとパスワードでならばログインすることも可能ですが、

今回のサーバーはアクセスするクライアントが固定なので公開鍵を使用します。

作成した公開鍵を下記のファイル名で保存します。

~/.ssh/authorized_keys

この時.sshフォルダの属性を700に、

authorized_keysファイルの属性を600に変更しておきます。

公開鍵を利用してアクセスできることが確認できたら

パスワードによるアクセスを制限します。

/etc/ssh/sshd_configファイルのパスワード認証をnoに変更し、

f:id:nomurabbit:20131208204300p:plain

その後、sshdを再起動します。


□起動プロセスの確認

起動プロセスはps axで確認します。

また、LISTEN状態のポートをnetstatで、

さらに外部からのポートの状態をnmapで確認します。

※どのプロセスがどのポートを使用しているかについては

lsofコマンドで詳細が見えるようです。

netstatで確認すると、22番ポートと25番ポートがLISTEN状態でした。

f:id:nomurabbit:20131208205233p:plain

22番ポートはsshにしても、25番ポートははSMTP

心当たりがないのでyumでインストールしたlsofコマンドで確認してみると

f:id:nomurabbit:20131208210525p:plain

やはり、smtpでLISTENされているみたいです。

そこで、runlevelとchkconfigを確認してみると、

f:id:nomurabbit:20131208210926p:plain

f:id:nomurabbit:20131208210934p:plain

いました!postfixがrunlevel3でonになっているようです。

不要なので下記のコマンドで切っておきます。

chkconfig --level 23 postfix off

最後にnmapで確認すると、22番ポートだけが空いています。

f:id:nomurabbit:20131208212722p:plain


□必要なパッケージのインストール

本題からは外れますが、下記のパッケージをインストールしておきます。

バージョンは特にこだわらないのでパッケージの管理はyumに任せます。

・nslookup
・traceroute
gcc
・make
・cpp
ghc(12/11削除)
perl
httpd(12/11追加)
・rpcbind(14/08/16追加)
vim(14/08/16追加)
・lsof(14/08/16追加)
・ntp(14/08/16追加)

※nslookupはbind-utilsパッケージに含まれます。

<まとめ>
今回までの作業で、sshでつなげて、yumが使えるようになりました。

また、余分なプロセスを切ることができました。

次回はWebサーバーをインストールしてCGIを作成してみることにします。

Linuxサーバー構築~その1~

<はじめに>
Linuxでサーバー構築を行う様を記録していきます。

下記の4つの役割を実装することを目標にすすめます。
・ドメインコントローラー
・ファイルサーバー
DNSサーバー
・バージョン管理サーバー


<作業内容>
まずはOSのインストールを行います。

今回構築するのはCentOS6.4です。

最終的にはHP ProLiant MicroServerに構築しますが、

今回は検証も兼ねてWindows7上のVirtualBoxにインストールします。

インストールの時に注意するのは2点です。


□ネットワークの詳細

f:id:nomurabbit:20131207010749p:plain

上の画像の「自動接続する」のチェックはデフォルトで入っていません。

このチェックが入っていないとOS起動後に手動でNICを有効にしないといけません。


□パーティションの分割

f:id:nomurabbit:20131207012044p:plain

今回は上の画像のように分割しました。

ファイルサーバーの割に /home が少ないのは

ホストOSのHDDの空き容量がわずかな故です。 ^^;

実際このあたりは自由に分割しちゃっていいと思います。

注意点として、基本パーティションは最大4つまでしか分割できません。

/ や 特に /boot なんかは基本パーティションに割り当てないといけません。

/home や /var なんかは拡張パーティションに割り当ててもおkです。


引き続きMinimalでインストールを続けて、

必要なものは随時インストールすることにします。


OSのインストールが無事に済んだら作業用のユーザーを作ります。

コマンドは下記。

# adduser <ユーザー名>
# passwd <ユーザー名>

本来ならこの時点でグループも決めた方がいいかもしれません。

今のところユーザーはroot、作業用、ファイルサーバー用の3つなので、

グループはスルーして進めます。

次に作業用のユーザーにsudo権限を付与します。

# visudo
//------------------------------------------------------
/etc/sudoers

# Arrows root to run any commands anywhere
<ユーザー名> ALL=(ALL) ALL // 追加
//------------------------------------------------------

これで、先ほど作ったユーザーで sudo コマンドが利用できるようになります。


さて、インストールの際にネットワークの自動接続に

チェックをしなかった場合はNICを有効にしないといけません。

まずは設定ファイルを編集します。

//------------------------------------------------------
/etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
HWADDR=FF:FF:FF:FF:FF:FF
TYPE=Ethernet
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ONBOOT=yes // ここをyesにすることで、起動時にNICが有効になるようです。
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=xxx.xxx.xxx.xxx // IPアドレスを指定します。
NETMASK=xxx.xxx.xxx.xxx // サブネットマスクを指定します。
GATEWAY=xxx.xxx.xxx.xxx // ゲートウェイを指定します。
//------------------------------------------------------

次にNICを有効にします。

#ifdown eth0 // eth0の無効化
#ifup eth0 // eth0の有効化

ついでにDNSサーバーも指定します。

//------------------------------------------------------
/etc/resolv.conf

nameserver xxx.xxx.xxx.xxx
//------------------------------------------------------


一通り設定し終わったら確認です。

ネットワークの設定は下記のコマンドで確認します。

#ifconfig // ネットワークの情報

#nslookup // DNSサーバーの情報

#traceroute // ルーティングの情報

#tracepath // ルーティングの情報

この時点ではnslookupとtracerouteはインストールされていないので、

後ほどパッケージをインストールしたときに確認します。


<まとめ>
この回ではOSのインストールとユーザーの作成、ネットワークの設定を実施しました。

次回はyumのリポジトリと浮いてるプロセスなんかを確認します。

また、次回以降必要なパッケージやサーバーをインストールしていきます。

F# で Oracle にアクセスしてみたよ!

<はじめに>
この記事は F# Advent Calendar 2013 7日目の記事です。

6日目は@masaru_b_clさんの F# InteractiveをConEmu上で利用する でした。

さて、F#を勉強し始めて、プライベートでちょいちょい書いていると、

「そのうち業務でもF#使いたいなー?」なんて妄想したりしますよね?

いざF#を業務に導入するとなると、

きっと既存の情報資産を活用できて、かつインパクトが少ない

例えば小規模なマスタメンテ用のWebサービスの作成ぐらいから

始めていくのが現実的かなー?なんて思ったりします。

今回はそんな来るべき日に備えて、

ADO.NETを使ってF#でOracleにアクセスする方法」

を覚書程度に書いてみました。

<対象データ>
下記のテーブルからデータを取得します。

f:id:nomurabbit:20131201223313p:plain

<プログラム1>
とりあえず、コンソールアプリケーションで単純にOracleからデータを取得してみます。

OracleClientはOracle.DataAccess.Clientを利用します。

open System
open System.Data
open System.Configuration
open Oracle.DataAccess.Client

[<EntryPoint>]
let main(args : string[]) = 

    // 接続文字列の取得
    let conStr = ConfigurationManager.ConnectionStrings.Item "connection"
    let con    = new OracleConnection(conStr.ToString())
    
    // SQLの定義
    let sqlStr = "SELECT * FROM MEMBER WHERE ID = 1"
    let cmd    = new OracleCommand(sqlStr, con)

    con.Open()

    // データの取得
    let reader = cmd.ExecuteReader()
    let result = reader.Read()
    
    // 取得したデータの出力
    printfn "%s %s %s %s" (reader.GetString(0)) (reader.GetString(1)) (reader.GetString(2)) (reader.GetString(3))
    
    reader.Close()
    con.Close()
    
    0

ちなみに接続文字列はApp.configから取得しています。

中身はこんな感じです。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="connection" connectionString="Data Source=XE;User ID=hoge;Password=fuga;"></add>
  </connectionStrings>
</configuration>

<実行結果1>
f:id:nomurabbit:20131201223320p:plain

上手くデータが取得できました!

<プログラム2>
目標はマスタメンテ用のWebサービスを作ることなので、

次はWebサービスを作ってみることにします。

open System
open System.IO
open System.Data
open System.Configuration
open Oracle.DataAccess.Client
open FSharpWcfServiceApplicationTemplate.Contracts

type Service1() =
    interface IService1 with
        member x.GetOracle value =

            // 接続文字列の取得
            let conStr = ConfigurationManager.ConnectionStrings.Item "string1"
            let con    = new OracleConnection(conStr.ToString())
            
            // SQLの定義
            let sqlStr = "SELECT * FROM MEMBER WHERE ID = " + value
            let cmd    = new OracleCommand(sqlStr, con)
            
            con.Open()
            
            // データの取得
            let reader = cmd.ExecuteReader()
            try
                try
                    let a = reader.Read()
                    sprintf "%s %s %s %s" (reader.GetString(0)) (reader.GetString(1)) (reader.GetString(2)) (reader.GetString(3))
                with
                    | :? FormatException as e ->
                        e.Message
                    | :? IOException as e ->
                        e.ToString()
                    | _  as e->
                        "???"
            finally
                reader.Close()
                con.Close()

<実行結果2>
デバッグで引数に"2"を渡して実行してみた結果がこちら。

f:id:nomurabbit:20131201224856p:plain

こちらも上手く値が返ってきました。

<プログラム3>
それでは最後に、C#で書かれた適当なクライアントから

先ほど作ったWebサービスをサービス参照で呼び出してみます。

public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    var webService = new FSservice.Service1Client();

    this.textBox1.Text = webService.GetOracle("3");
}

<実行結果3>
f:id:nomurabbit:20131201230943p:plain

おー!値が取得できました!

<まとめ>
F#を使って(というかADO.NETを使って)Oracleにアクセスすることができました。

取得したデータをF#でいかに扱うかを勉強していきたいと思います。

F# AdventCalender 2013 7日目は以上です。

明日は@n_enotさんの「F# で System.Reflection(仮)」です。