VPSによる公開サーバーの構築 (CentOS)

この記事は、DTIのVPSサーバーでサーバーを立ち上げる際に手順をまとめたものです。 IPアドレスさえ付与されていれば、さくらのVPSやその他のVPSの環境であれば利用できると思います。 それなりのセキュリティ、それなりの利便性を、最近普及が進んだVPS等の新しい技術を活用して構成したサーバーです。

サーバーOSはCentOSを想定しています。一部、手元のマシンがWindows前提で書かれた箇所があります。

相当の長文です。以下、記事本文です。

本文

はじめに

DTIのVPSは、よく聞く仮想化基盤(基盤=インフラストラクチャー)であるXen,KVM,QEMUではなく、 OpenVZということを念頭に置いておいた方が良さそうです。 2014時点で個人のLinuxマシンで、仮想化するといえば上記の3つが主な選択と思います。 OpenVZは、仮想化する階層が異なっていて、マシンのリソースを効率よく使える分、 カーネル空間が一つだったりでゲストマシンのカーネルを入れ替えたり出来ず 柔軟性は欠けるようです。

一番身近な弊害は、カーネルを再コンパイルするような方法は取れません。

この記事の前提条件

bitbucket等、グローバルインターネット空間でプライベートリポジトリを持てる状態。 固定IPアドレスを持っている。サーバーOSはCentOS (version 6)。

サーバーの仕様

  • 主な仕様
    1. sshでのアクセス
    2. ipv6は無効
    3. httpサーバー
    4. VPS(softether)
    5. firewall(インターネット側は制限。VPN側はフリー)
    6. メールの送信機能(smtpのクライアント機能のみ)
  • VPN (Virtual Private Network) 内でのサービス
    1. VPN内からサーバーへの経路
    2. wan側(インターネット側)へのアクセス。
    3. sambaサーバー
    4. ルーター機能
    5. dhcp
    6. webminやMunin等の内部専用のwebページ
  • その他縦断的なもの
    1. Webmin…webブラウザから、サーバーのメンテナンスを行うもの。かなり便利
    2. cron…クーロン。スケジュールに基づいて、コマンドやシェルスクリプトを自動実行するもの。
    3. syslog…ログメッセージをやり取りする規格。ログを一元管理する目的で利用される。
    4. logrotate…ログの肥大化を防ぐため、定期的に古いログを圧縮したり削除を行うコマンド。
    5. logwatch…ログ監視ツール
    6. munin…サーバ監視ツール
    7. AWStats…Web等のアクセスを解析するツール。
    8. Tinkererの便利な環境…bitbucketへpushするだけで、git pull→tinkererビルド→web公開が行われる環境

SSHの設定

サーバー内のVPNでSAMBAを解してファイルをやり取りできる状況を目指します。 そこに至るまで、結構な手数を要します。 sambaが繋がるまでのファイル転送はgitか、sshのターミナルでクリップボードを貼り付けるかになると思います。 gitを利用する場合は、bitbucketあたりにプライベートリポジトリを作って、 ローカルマシンにクローン。適宜利用ください。サーバーの設定ファイルや、 設定用のスクリプトを管理するのにもgitは結構便利です。 etckeeper等も活用できるようであれば、併用ください。

まずは、サーバーをメンテする上で、実質一番基本的な通信であるSSHの設定です。

sshクライアントは、WindowsではPuttyがお勧めです。鍵が独自の形式で変換する必要が あったりしますが、説明してくれているページが多数あります。

まずは、認証鍵方式でのSSH接続を構成:

$ passwd #rootのパスワードをデフォルトから変更
$                  #sshログイン&rootになることを許可するユーザーを作成する
$ useradd testuser #時間があれば、useradd -Dで作成されるユーザーの設定を確認どうぞ
$ passwd testuser #パスワードはセキュリティの高いものにすること
$                 #本時点では、このパスワードだけで世界中からssh経由でこのマシンにログインできます。
$ su testuser
$ cd
$ ssh-keygen      #sshのキーを作る。適当にエンター。但し、キーが漏れた場合に備えパスフレーズ設定を推奨します。
$ cd ./.ssh
$ vim ./id_rsa    #クリップボードへコピーしてputtygen等でキーを変換して、手元マシンの適切な場所に配置
$ rm ./id_rsa     #サーバー上の秘密鍵id_rsaはもう要らないので消しておきます。
$ mv  id_rsa.pub authorized_keys #公開鍵を、SSHD規定のパスへ移動しておく。
$                                #厳密に書くと ~/.ssh/authorized_keys

一度コンソールを閉じて、秘密鍵を利用してsshログイン。(puttyの場合は、 openssl形式からputty形式へ鍵を変換したり等の手順が必要) ログイン時に鍵による、ログインが成功することを確認。 鍵が受け付けられなかったというようなメッセージがログイン時に 表示されている場合はNGです。再度確認の上、やり直してください。

Git周辺のセットアップ

とりあえずでローカルとリモートでファイルをやり取りしたいので、 gitを使えるようにする。rootで設定ファイルの置き換え等にも利用したい。 設定ファイルや作業をスクリプト化したものがあれば、 ここでgit経由でUPしてしまえば、以後の作業は自動化できる。

testuserでログインした状態からスタートです。:

$ su root
$ cd
$ mkdir ./.ssh -m 700
$ vim .ssh/bitbucket_ssh_key   #bitbucketのsshキーを貼り付け。
$           #コピーするキーは、opensslの形式なのでご注意を。パスフレーズ無しにしておけば便利です。
$ chmod 700 ./.ssh/bitbucket_ssh_key  #このファイルは他人に見られるとまずいので
$ vim ./.ssh/config

で以下をペースト:

Host bitbucket.org
  IdentityFile ~/.ssh/bitbucket_ssh_key

さらに:

$ chmod 700 ./.ssh/config
$ yum install git -y
$ git clone git@bitbucket.org:somename/some_repo.git

後ついでに、etckeeperも入れておく。 これは、/etc以下をgitで管理してくれるというもの。 とりあえず入れておけば、後で履歴は見れます。 /etc/.gitが作成されます。/etc内でgit diffすれば差分が見れる状態になります。 また、cronで毎日保存され、yumが動作した際も自動的に保存されます。 (/etc以下で、頻繁に書き換わるバイナリファイルなどがある場合は注意ください。 ただ、通常不要と考えられるものは/etc/.gitignoreで無視される設定になっています。)

SSHの設定2

順序が多少前後していますが、引き続きSSHの設定です。

$ su
$ cd /etc/ssh
$ vim ./sshd_config

以下のオプションを確認:

Protocol 2                # SSH2による接続のみ許可
RSAAuthentication no
PubkeyAuthentication yes
PermitRootLogin no         # rootでの認証を禁止
RhostsRSAAuthentication no # rhostsでの認証を禁止
PasswordAuthentication no  # パスワードでの認証を禁止(公開鍵による認証のみにする)
ChallengeResponseAuthentication no # チャレンジ/レスポンス認証を無効化する
SyslogFacility AUTHPRIV    # ログ出力ファシリティの指定
LogLevel INFO              # ログ出力レベルの指定
AllowUsers testuser        # SSH接続可能なユーザーを限定
UsePAM no
#Subsystem     sftp    /usr/libexec/openssh/sftp-server #sftpは利用しないのでコメントアウト

上記には記載していませんが、ポートをデフォルトのものから変えておいた方が、 セキュリティ上好ましいです。

wheelの指定

wheelはrootになることが出来るグループです。 この項では、rootになることが出来るユーザーを制限します。

/etc/groupのwheelにカンマ区切りでユーザーを追記:

wheel:x:10:root,testuser

/etc/pam.d/suで以下の行のコメントアウトを取り消す:

auth required /lib/security/$ISA/pam_wheel.so use_uid

許可されていないユーザーからsuを試みて、su出来ないことを確認して終了。 間違っても、rootになれない状況は避けてください。

ipv6やSELinuxの無効化

ここらへんはややこしいので、とりあえず無効にしておきます。

SELinuxが無効なことを確認。有効であれば無効化:

$ getenforce

次にipv6を実際に無効化。 真偽未確認ですが、ipv6とSELinuxは依存性があるらしいです。 というか、ipv6を無効にした時…何かしらのプログラムでバグがでる時があります。 一度出会ったのは、localhostにアクセスしようとすると、ipv6で アクセスを試みるようなツールがいました。

ipv6の無効化:

$ echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
$ echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
$ sysctl -p       #設定を反映
$ #エラーがでたので、sysctl.confのnet.bridge.bridge-nf-call-ip6tables
$ #らへんもコメントアウトしてから、再度sysctl -pしました。
$ #さらに
$ echo 'options ipv6 disable=1' > /etc/modprobe.d/disable-ipv6.conf
$ chkconfig ip6tables off
$ shutdown -r now  #何かしらの機能に影響があるので再起動
$ #再起動後rootになってから
$ ifconfig         #結果に、ipv6の設定が表示されないことを確認
$ chkconfig --list|grep ip #ip6tablesが無効なことを確認

iptabelsの設定(ファイヤーウォール、ルーティング)

この設定はミスするとSSHで接続できなくなるので注意ください。

次は、iptablesでファイアーウォールとパケット変換の設定。これは、難しいww 何十万するようなルーターの機能を設定できる位には複雑ww

とりあえず、iptablesの処理は以下の図のような経路に沿って行われます。上が入力で下が出力、左側はローカルマシン(厳密にはLocal Process)が存在する経路で、右側はフォワーディングです。

mangle,nat,filterっていうのはテーブルです。 PREROUTING,INPUT,OUTPUTというのは経路の位置を表す、チェインと呼ばれるものです。 mangle,filter,natは役割を現す、テーブルと呼ばれるものです。 テーブルとチェインの要素を組み合わせて、作用させるルールの位置を定義できます。 色々な言葉の説明を読むよりは上記の図をみて、パケットがどの経路を通るか考えて、ルールを考えることをお勧めします。

後、アドレス変換のMASQUERADやSNATは、POSTROUTINGチェインのnatテーブルに設定する必要がある等の縛りが有ります。これは、おそらくネットワークに詳しい人からすると、SNATは送信元のipアドレスを変換するものだから当然、というように常識に近い部分なのでしょうがなかなか取っ付きにくいです。(DNATは宛先IPの変換でPREROUTINGのnatで変換されるものです。これは市販ブロードバンドルーターのポート開放の機能に相当)

ファイアーウォールのようにパケットを破棄するルールを記載するのは基本的に、filterテーブルです。 一旦全ての経路を禁止した状態から通す経路を一つ一つ定義していくのが 一般的なアプローチのようです。

たちが悪いのは、一つの機能のパケットを通すとして、その機能が利用する 全てのパケットの経路を漏れなく把握する必要があるってとこでしょうか? windows xpがsambaにアクセスする時に、条件次第でwebdavのポートも 見に行く動作をしてることは、それなりの労力払わないと知ることは出来ないでしょ。 というのが著者の理解ですが、間違いの少ない情報はオフィシャルで勉強頼みます。

とりあえずで書き上げた、iptables設定のスクリプトが以下。 /etc/rc.d/init.dに以下のスクリプトを配置して、chkconfig onすると使用できます。

ルーティングの機能の設定も入っています。

filtertabファイル:

#/bin/sh
#
# chkconfig: 2345 99 92


WAN_IF=venet0
#ipエイリアスはiptablesでは上手く使えない???っぽいので使わない
LAN_IF=tap_sometap

LOOPBACK_ADDR=127.0.0.0/8
CLASS_A=10.0.0.0/8
CLASS_B=172.16.0.0/12
CLASS_C=192.168.0.0/16
CLASS_E=240.0.0.0/5

#自ホスト、プライベートIPアドレス設定
WAN_ADDR=36.12.134.156
LAN_ADDR=192.168.200.2
LAN_IP_RANGE=192.168.200.0/24

#flush all chain
iptables -F
iptables -t nat -F
iptables -X
iptables -Z

#一旦全部DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

iptables -N wan_server
iptables -N server_wan
iptables -N server_lan
iptables -N lan_server
iptables -N wan_lan
iptables -N lan_wan

##チェインに属性を割り振るって幹事
iptables -A INPUT -i $WAN_IF -j wan_server
iptables -A OUTPUT -o $WAN_IF -j server_wan
iptables -A OUTPUT -o $LAN_IF -j server_lan
iptables -A INPUT -i $LAN_IF -j lan_server
iptables -A FORWARD -i $WAN_IF -o $LAN_IF -j wan_lan
iptables -A FORWARD -i $LAN_IF -o $WAN_IF -s $LAN_IP_RANGE -j lan_wan

#ログ取りの設定
iptables -N log_drop
iptables -A log_drop -m limit --limit 1/s -j LOG
iptables -A log_drop -j DROP

for i in $CLASS_A $CLASS_B $CLASS_C $CLASS_E $LOOPBACK_ADDR
do
        iptables -A server_wan -d $i -j log_drop
        iptables -A wan_server -s $i -j log_drop
done

iptables -A server_wan -d 255.255.255.255 -j log_drop
iptables -A server_wan -d 224.0.0.1 -j log_drop
iptables -A wan_server -d 255.255.255.255 -j DROP
iptables -A wan_server -d 224.0.0.1 -j DROP

#spoofing(ip addressの偽装)を防止
iptables -A wan_server -s $WAN_ADDR -j log_drop
#iptables -A wan_server -s $WAN_ADDR -j DROP


########################################
#lo policy
######################################
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT


####################################
#WAN---->Server
#################################
#pingだけ通す
iptables -A wan_server -p icmp --icmp-type 0 -j ACCEPT
iptables -A wan_server -p icmp --icmp-type 8 -j ACCEPT
#確立された接続のパケットは通す
iptables -A wan_server -m state --state ESTABLISHED,RELATED -j ACCEPT
#その他不特定多数に空けたいポート
iptables -A wan_server -p tcp --dport 22 -j ACCEPT  #SSHのポート
iptables -A wan_server -p tcp --dport 80 -j ACCEPT  #http
iptables -A wan_server -p tcp --dport 443 -j ACCEPT #https


#VPNのポート関係
iptables -A wan_server -p udp --dport ***利用するプロトコルにあわせて設定**** -j ACCEPT
iptables -A wan_server -p udp --dport ***利用するプロトコルにあわせて設定**** -j ACCEPT
iptables -A wan_server -p udp --dport ***利用するプロトコルにあわせて設定**** -j ACCEPT

#######################################
#server---->wan
####################################
iptables -A server_wan -j ACCEPT

######################################
#server-->LAN
##################################
iptables -A server_lan -j ACCEPT

###########################################
##LAN -----> SERVER
###########################################
iptables -A lan_server -j ACCEPT

##########################################
##lan---------->wan
###########################################
iptables -A lan_wan -j ACCEPT

##################################
#lan -----> wan port forwarding
##################################
iptables -t nat -A POSTROUTING -o $WAN_IF -s $LAN_IP_RANGE -j MASQUERADE

###################################3
#WAN--->LAN  PORT FORWARDING
####################################
iptables -A wan_lan -m state --state ESTABLISHED,RELATED -j ACCEPT

上記設定ファイルでlanを含む行は、softetherでtapデバイスを作成するまでは記述しないで下さい。 vimだとコマンドモードで :%s/\(.*lan.*\)\c/#commentout\1 / でコメントアウトが行えます。コメントアウトをなくす時は、"#commentout "を除去してください。

本ファイルに実行属性を与えて 実行すれば、設定の確認が行えます。

動作の確認が行えれば(エラーが発生せず、sshが接続できることを確認)、とりあえずfiltertabを起動時の最後に実行するように設定します。 ↑のようなファイル(先頭のchkconfigのコメントが重要)に対して以下のコマンドを実行して、起動時に実行されるようにする:

$ cp ./filtertab /etc/rc.d/init.d/
$ chkconfig --add filtertab
$ chkconfig filtertab on
$ chkconfig --list |grep filter        #設定されたか確認。
$ ls /etc/rc.d/rc3.d/ -la |grep filter #設定されたか確認。
$ shutdown -r now #再起動して動作確認
$ #再起動後rootで意図通り動作してるか確認。
$ iptables-save |more

ここまでで、公開サーバーとして問題ない位のセキュリティにはなったはずです。 これで、外部との通信は、管理者のコントロール下にある状態で、 許可された通信はセキュアなものになっているはずです。 (でなければその項目教えてくださいm(_ _)m 把握していない経路が未設定でセキュリティ ホールが残っているというのは許されないです。 DOS攻撃とかは落ちるでしょうけどww)

VPNのインストール

というわけで、vpn等でいろいろ経路を作っていって便利にしちゃいましょう。 ローカルのネットワークドライブへUPする感覚で、サーバーへファイルUP できるようにすることを目指して触ります。 このネットワークドライブは仲間内で共有できるようにすることも意識しながらいきます。

vpnはプロトコルが色々あって、ややこしいです。 ネットワーク層は7層に分かれていますが、どの層でトンネリングを行うか等で 色々種類があります。 例えば以下

  • l2tpは第二層のトンネリングで、これに第三層の暗号化を行うIPSecと組み合わせてl2tp/ipseとして利用されます。
  • IPSecVPNは、第三層でトンネリングと暗号化が行われます。
  • pptpは第二層でトンネリング&暗号化が行われるようですが、セッション確立時にセキュリティ不足なようです。
  • SSL-VPNは第4層あたりのものです。
  • sstpというものもあるようです。

このように乱立しているので、利用するプロトコルをどれにするかは 前以て決めてからかかったほうが良さそうです。 その他詳細は、ネットで調査お願いします。 今回は、2014時点でクライアントが良く普及してそうな l2tp/ipsecにターゲットを絞って導入を行います。

l2tp/ipsecをcentosで使用する方法ですが、 通常のxl2tpd+openswanが多いようです。 他にもsoftether VPN Serverがあるようです。

今回は、以下の理由でSoftEtherを選択してみます。
  • 対応しているプロトコルが多い
  • CUIサーバーでも、手元のwindowsマシンでGUIで設定が行える

オフィシャルで、コマンドライン操作はマニュアルの熟読が必要と 書いてあるので、GUIの「サーバー管理マネージャー」で管理をやってみます。

ネットワークの構成を決めておきましょう。

  • IPアドレスの空間: 192.168.200.0/24
  • サーバー(dhcp,gateway,dns等): 192.168.200.2
  • dhcp割り当て範囲: 192.168.200.101-254

さくらのVPSへVPN経由で繋いでみた 」と被っている手順もありますし、一部リンクさせていただきます。 このページは参考資料として結構いいページと思われます。

$ yum install -y gcc make binutils libc-devel zlib-devel openssl-devel readline-devel ncurses-devel pthread-devel #いくつかエラーが出るけども無視
$ wget http://jp.softether-download.com/files/softether/v4.10-9505-beta-2014.10.03-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.10-9505-beta-2014.10.03-linux-x64-64bit.tar.gz #ダウンロード
#
#以下インストール
#
$ tar xvf ./softether-vpnserver-v4.10-9505-beta-2014.10.03-linux-x64-64bit.tar.gz
$ cd ./vpnserver
$ make
#makeする間に何度か1を入力
$ chmod 600 *
$ chmod 700 vpncmd
$ chmod 700 vpnserver
$ cd ../
$ mv vpnserver /usr/local
$ vim /etc/init.d/vpnserver

以下のスクリプトを入力

#!/bin/sh
# chkconfig: 2345 64 01 #dhcpdの前
# description: SoftEther VPN Server
DAEMON=/usr/local/vpnserver/vpnserver
LOCK=/var/lock/subsys/vpnserver
test -x $DAEMON || exit 0
case "$1" in
start)
$DAEMON start
touch $LOCK
;;
stop)
$DAEMON stop
rm $LOCK
;;
restart)
$DAEMON stop
sleep 3
$DAEMON start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0

引き続き作業

$ chmod 755 /etc/init.d/vpnserver
$ chkconfig --add vpnserver
$ service vpnserver start

以上でインストール完了です。

次は、「 さくらのVPSへVPN経由で繋いでみた 」参照で、 私の環境では、最初の接続時、httpdのポート443がかちあったので、 最初の設定時だけはhttpdを落として 行いました。 それから、サーバー管理マネージャーでポート443を停止にしておきました。 ただし、「さくらのVPSへ…」と違ってDHCP無効の上で、tapデバイスを作成してください。

以下のようなコマンドで、linux側をvpnに繋ぐ:

$ ifconfig tap_vpn1 192.168.200.1 netmask 255.255.255.0

softehterの起動スクリプト(/etc/rc.d/init.d/vpnserver)に、下記の2-3行目の行を追加。 start時とrestart時で 二箇所 です。:

$ $DAEMON start
$ sleep 3
$ ifconfig tap_vpn1 192.168.200.1 netmask 255.255.255.0

再起動してからでも、routeコマンドで192.168.200.0の設定があることを確認。 GenMaskも上記で設定したNetmaskになっていることを確認。 もしなっていなかったら、route -add的な作業が必要です。

次は、softetherを設定するにあたって下準備で、 LAN側からWAN側へのアクセスを設定します。 今回は、VPS内のLAN側デバイスに インターネットアクセスを提供します。 こういう場合は、知る限りカーネルオプションと iptablesを設定すればOKです。

まず、再起動後も設定が保持される方法でカーネルオプションを設定。/etc/sysctl.confで以下を行う:

net.ipv4.ip_forward = 1

その後:

$ sysctl -p

iptablesは、上部で貼り付けたものを参照ください。 重要な設定は以下です。:

iptables -A FORWARD -i $WAN_IF -o $LAN_IF -j wan_lan
iptables -A FORWARD -i $LAN_IF -o $WAN_IF -s $LAN_IP_RANGE -j lan_wan
iptables -A server_lan -j ACCEPT
iptables -A lan_server -j ACCEPT
iptables -A lan_wan -j ACCEPT
iptables -t nat -A POSTROUTING -o $WAN_IF -j MASQUERADE
iptables -A wan_lan -m state --state ESTABLISHED,RELATED -j ACCEPT

LAN側は利便性優先で、基本的にガードしない状態にしときます。 -j MASQUWERADEしている行だけで、ブロードバンドルーターの役割をほぼこなせるとのこと。 -j MASQUWERADEは-o $WAN_IFだけでいいのに疑問を感じたから軽く調べてみると、 LANが最初にパケットを飛ばしたら、POSTROUTINGでアドレス変換テーブルに登録しておけば、 WANからの応答はPREROUTINGでアドレス変換できるだろうから、-o $WAN_IF側の 設定だけでいいんでしょうね。余りそこまで言及してくれるサイトには辿り着けなかったです。 逆にWANがLANに向けて最初にパケットを飛ばす場合は、 PREROUTINGのDNATでアドレス変換テーブルに登録するんでしょうね。 こちらは、ポート開放と俗に言われてるやつですね。 んだから、アドレス変換テーブルに登録しないといけない場合だけに MASQUERADEとDNATを設定すればいいんでしょう。 iptablesのオプション構造的に、dnatとsnatが対照的な動作みたいです。 動的なIP割り当ての際は、snatではなくMASQUERADEを利用しろとのことです。

実質、一般的な環境ではdnatとMASQERADEが利用されることになるようです。

http://www.turbolinux.com/products/server/11s/user_guide/x9664.html

filtertabを変更すれば、filtertabを実行して反映&動作確認して下さい。

DHCPの設定

$ cat /etc/resolv.conf     #予めdnsのアドレスを確認
$ yum -y install dhcp      #インストール
$ vim /etc/dhcp/dhcpd.conf #設定ファイルをオープン

設定ファイルを編集:

#ddns-update-style interim;     #dynamic dnsの設定。これは使わない
ignore client-updates;
authoritative;

subnet 192.168.200.0 netmask 255.255.255.0 {

# --- default gateway
        option routers                  192.168.200.1;       #ゲートウェイ
        option subnet-mask              255.255.255.0;
        #option nis-domain              "*******.com";      #これはコメントアウトかと。。
        option domain-name             "*******.com";       #ドメインを持っていればそれを記載
        option domain-name-servers      202.216.224.30;     #DNSサーバーのアドレス(固定IP設定であれば/etc/resolv.confに記載されてる)
        option domain-name-servers      202.216.229.30;     #DNSサーバーのアドレス
        option time-offset              -18000; # Eastern Standard Time
        range dynamic-bootp 192.168.200.100 192.168.200.254;     #割当てるIPアドレスを指定
        default-lease-time 21600;
        max-lease-time 43200;

        # we want the nameserver to appear at a fixed address
        #host ns {
        #       next-server marvin.redhat.com;
        #       hardware ethernet XX:XX:XX:XX:XX:XX;
        #       fixed-address 207.175.42.254;
        #}
        }
}
#host win-client1 { ← ホスト名
#       hardware ethernet XX:XX:XX:XX:XX:XX; ← win-client1に装着しているネットワークアダプタのMACアドレス※
#       fixed-address 192.168.1.10; ← win-client1に固定で割当てるIPアドレス
#}

起動&自動起動有効化:

$ chkconfig dhcpd on
$ service dhcpd start

VPNへの接続

ここまですれば、一回windowsで繋いでください。 /etc/init.d/dhcpd内記載の /var/lib/dhcpd/に、払い出したIPアドレスが記載されています。 確認してみましょう。 もし出来ていないなら、dhcpのポートを塞いでいないか等確認してみたって下さい。

さらに、windows側から ping 192.168.200.1 して見て下さい。返ってくれば、VPNはできています。

windows側の、ネットワーク接続内のVPN接続アダプタを右クリックプロパティで、 TCP/IPv4のプロパティの詳細設定で、、、 →リモートネットワークでデフォルトゲートウェイを使うにチェックを入れる。 で、windowsを再度接続してみましょう。

IPアドレスとホスト名を表示してくれるサイトを開いてください。 サーバーのものになっていれば成功です。VPN yes!!! かなり色々なものをつなげることが出来ました。お疲れ様です。

次は、上記のwindows側のvpnのゲートウェイのチェックを外してから、 ブラウザのアドレスにサーバーのローカル側のIPを入れて開いてみましょう。 そのページは、VPNのLAN側からアクセスしたページです。 グローバルアドレスを入れれば、WAN側からアクセスできます。 中々、乙な環境と思うのですがww

ただ、間違ってtorrent等起動中に、ゲートウェイをサーバーに しないように注意下さいwww

webmin等の管理用をローカル側からしかアクセスできないようにするのは、 セキュリティ的に好ましいです。

SAMBAの設定

とりあえずで、sambaにログインできる状態を作り上げることを目標にします。 書くのが少し疲れたので、細かい設定などは、他ページを調べてください。 多人数で利用する場合は、グループ設定を行っておくと便利です。:

$ vim /etc/samba/smb.conf

printersの項目は丸ごとコメントアウト homesの項目は、デフォルトのままで。

次に:

#testuserにsambaパスワードを設定。
$ smbpasswd -a testuser
# 次はsamba起動。
$ service smb start
$ chkconfig smb on
$ service nmb start
$ chkconfig nmb on

windows側で、\192.168.200.1 にアクセス。testuserのアカウントでログイン homeディレクトリを開いて、ファイルを新規作成して、 それを削除してください。

以上で、書き込み権限まで確認できました。

2014/12/11追記

VPN経由だとSAMBAの通信が著しく遅いようです。
詳細は"cifs vpn 遅い"等で検索してください。
著者の環境だと、右クリックが以上に遅かったのでWebdav要因で遅くなる件と混同しかけましたが、
VPNが原因のようです。
著者の環境(Centos 6.x + Windows 7)でこれの対応には、SMB2.0の利用が若干の効果がありました。
やり方は,smb.confファイルの[global]セクションで以下二行を追加。
max protocol=SMB2
min protocol=SMB2
これでサーバー側が、SMB2での接続しか許可しなくなります。
Windows XPで利用する場合は、これに対応できないのでmin protocolを削除してください。

webサーバーの設定

省略。/etc/httpd/conf/と、/etc/httpd/conf.d/以下に設定ファイルがあります。デフォルトでは、cgi-bin以下がcgiの実行パスですが、この制限は取っ払った方が便利です。 後実行ユーザーについては、webサーバーを利用するユーザーが数人以下程度であれば、apacheのままで運用のが手軽と思います。 httpadmin的なユーザーを作成し、ユーザーapacheとwebを編集するユーザーを、グループhttpadmin追加。 また、webのルートディレクトリは、setgidをしておいて、新規に作成されるファイルやディレクトリのグループをhttpadminとなるようにする。

以上で、グループ権限を活用して運用できます。

以下例:

$ useradd httpadmin
$ chown httpadmin /var/www/html
$ chgrp httpadmin /var/www/html
$ chmod 2775 /var/http           #setgidをする。
$ usermod -G httpadmin testuser
$ usermod -G httpadmin apache

その他、基本的な設定

文字コードの修正:

$ vim /etc/sysconfig/i18n

LANGを"ja_JP.UTF-8"へ

ホスト名の修正:

$ echo  "HOSTNAME=********.com" >> /etc/sysconfig/network
$ vim /etc/hosts

以下を追加:

127.0.0.1 localhost.localdomain localhost *********.com

サーバーを再起動

SAMBAとVPNの自動接続

Windows起動後、一々接続するのは面倒くさいのでスクリプトにしておきましょう。

rasphone -d "vpn_connection_name"
NET USE \\192.168.200.2 /USER:username password
timeout /T 2

上記の.batファイルをスタートアップ等に置いておけば、ログイン後 自動的にVPN接続と、SAMBAの認証が行われます。 ネットワークドライブにマウントしたり、ログイン前から行いたい場合等、 別の方法を行う方は各自で書き換えてください。

※rasphoneコマンドの詳細は→ http://unyouchan.blog.jp/archives/1003946859.html

SAMBAのログファイルのカスタム

デフォルトでマシン毎にログファイルをわける設定になっているが、 そんな10人も使用しない場合は必要が無いので統合しておく。 で、一応ファイルのアクセスログは残しておきたいので、log levelは2にしておく。 log level2はそれなりの量のログが書き出されるのでサイズも5M程度にしておく。 パフォーマンスは犠牲にします。 また、samba起動時にfailed to retrieve printer list: NT_STATUS_UNSUCCESSFULが 表示されたのでload printers = noにしておく。

さらに込み入った設定やツールのインストール

以降では、さらに込み入った設定を行います。 目標はTinkererの環境を整えることです。

Munin(サーバー監視ツール)

mrtg,cacti,munin等いくつかのサーバー監視ツールがあります。Muninは簡単らしく、少数のサーバーであれば十分そうです。サーバー監視ツールの設定スクリプトは、ある程度勉強しないと、意味不明で難しいので出来るだけ触ることを避けます。

$ yum -y install munin --enablerepo=epel   #eoekリポジトリ追加していなければ外部サイトで方法を確認して下さい。
$ htpasswd -b /etc/munin/munin-htpasswd munin admin   #パスワードの設定(basic認証用のん)
$ service httpd restart
#logrotateとlog取得ルールの設定。→webで、サーバー側のhtml生成時間はデフォルトで入っていない
#日本語環境だと、曜日、日付部分が文字化けするようなので、
$ vim /etc/cron.d/munin
#
#LANG=Cを追加
#*/5 * * * *     munin test -x /usr/bin/munin-cron && LANG=C /usr/bin/munin-cron
$ service munin-node start
$ chkconfig munin-node on

5分経過後にhttp://somehost.com/munin/にアクセスしてみる。

Webmin(サーバー管理ツール)

webminのインストール:

$ yum -y install perl-Net-SSLeay
$ rpm -Uvh http://prdownloads.sourceforge.net/webadmin/webmin-1.710-1.noarch.rpm

インストールが終われば、ローカル側からサーバーのポート10000へ ブラウザでアクセスしてみます。 上記バージョンでは、httpsでしかログインできません。 httpでログインできないことを確認して下さい。 とりあえずログインして、Change Language and Themeから、 Webmin UI languageでjapaneseを選んで日本語化しときましょ。

Pythonのバージョンアップ

pythonのバージョンを2.7系のものに入れ替えておく。 centos6はpythonが2.6で新しいツールを利用する時にエラーの原因になるため。 以下のページを参照にするが、、確か、騙し切れていないところがあったと思う。 何かまずいところあれば自己解決頼みます。 リンクが上手いこといってないない程度のエラーのはずです。 http://next.matrix.jp/20130602.html

細かいTIPS(細々した動作確認と、動作設定)

  • iphone及びandroidから、wifi経由及び3G経由でのVPN接続。 さらにVPNを経由してのインターネットアクセスを確認。
  • iphone及びandroidから、NASへのアクセスの確認。
  • イントラ側のトップページを設定
  • イントラ側でwikiを導入→サーバーのメンテ情報等をまとめるため。
  • apacheのドキュメントルートの変更
  • SAMBAのチューニング、cgiをupすればそのまま実行できるパーミッション設定

awbstats(WEBアクセス解析ツール)

$ yum install awstats --enablerepo=epel #2014/10時点では、この時点で大体設定が終わっている。

設定ファイルは、/etc/awstats/awstats.***ホスト名****.conf awstats.model.conf以外の物が全て解析されます。

以下を確認&設定。

  • SiteDomainが自分のサーバー名(***.comやlocalhost.localdomain等)になっていること
  • DNSLookupを確認(とりあえず1?)
  • SkipHostsを変更。"127.0.0.1 REGEX[^192.168.1.]"でLAN側のホストを無視できる。
  • Langを"jp"へ
  • DirDataを確認。ここにDBが保存されます。 一からDBを生成し直すときは、このディレクトリ内のファイルを削除
  • vi /etc/httpd/conf.d/awstats.confしてbasic認証等、適当に外部から見れないようなルールを設定してください。
apache再起動したら以下でデータを生成::
$ /usr/share/awstats/tools/awstats_updateall.pl now -awstatsprog=/usr/share/awstats/wwwroot/cgi-bin/awstats.pl

上部に記載したとおり、awstats.model.conf以外が解釈され、 DirDataへ解析されたデータが保存されます。

yumでインストールした場合は、自動でcronのhourlyに登録してくれていましたので、以上で終了です。

Tinkerer(ブログテンプレートエンジン)

この章はメモ書き程度のものです。

bitbucketのhook機能による連携

gitにはhookと言う機能があります。これはgitに特定のアクションが発生した時に、スクリプトを実行するようなものです。Bitbucketはwebページからこの設定を行えます。

今回は、BitbucketにpushするだけでTinkererをサーバー側でビルドするために利用してみました。

以下手順

  1. とりあえず、httpsでbasic認証出来る状態にする。
  2. httpdを動作させているユーザーでgit pull出来る状態にする。
  3. git pullをしてtinkererをビルドするとこまで行うスクリプトを作成。
  4. basic認証されるパスに上記のスクリプトを実行するcgiを配置
  5. bitbucketのhookのPOSTを追加。記述URLは次のようなもの、https://username:password@somehost.com/some.cgi

あまりきれいなやり方じゃないですが、gitでpushするだけでサイトの更新が終わります。 →VPN経由のipmsg等でビルドの成否まで返すのはありかもしれません。私の場合は、イントラ内でwebから、ビルドログをみれるようにしています。

ログ監視ツール

ドメインとってサーバーを公開していると… 結構言う人が多いですが、アタックを受けますww 数日間のアクセスログ見ちゃいましょうww 管理人のんで目立ったのは、wordpressの管理ページでした。 他にもphpmyadmin等の系統のweb管理ページも狙われるようです。 SQL系のが狙われるのは、SQLインジェクションでも狙ってるんでしょうか??。 商用サイトがSQLインジェクションで良く落とされるのは。。 これの穴を埋めるのは金にならない仕事だからでしょうかねww 発注側はそんな得体の知れないものにお金を払えるかって感じでしょうか? そんなことよりもっと高機能な○○を作ってくれ?? 関わったことのない仕事ですが、なんとはなくその様な社会の仕組みを感じますww 攻撃側からしたら、そら足元がガラ空きだったら突っついて みたくなるんは人の性ってやつ??適当な物言いですがww

文字をやたら書いているのでついでに書いておきます。
  1. ログ取りはまずログを残す条件やログの文字列の定義が必要です。 これは、各モジュールのconfファイル等に記載されることが多いです。
  2. 次に、各モジュールから投げられてくる様々なログを一元化し、 モジュール名やエラーレベル等も含めて体系的に収集してくれる モジュールがあります。 Linuxでは、syslogと呼ばれるものです。
  3. 次に、大量に集まったログはアーカイブ化して置くと便利です。 これは、logrotateです。
  4. また、集めたログは分析する必要があります。 これを助けるツールはlogwatch等です。 httpd用にはAWStatsや、webalizer等様々です。

だから思い通りのログ取り環境を目指すには、1~4までを適切に設定する必要があります。 また、swatchの様にリアルタイムでログを分析し、条件に合致すれば アクションを行うツールもあります。 これらの仕様はそれなりの文章量ですので、各々を専門に 記述したWebページを参照ください。 ただ、4部分はOSの標準では無く、apacheは2を飛ばして単体で /var/logへログファイルを書き出したり、色々とバリエーションが有ります。 とりあえず、後で取り返しが付くレベルの設定だけしておきます。

さらに、ログ管理もやっちゃいましょう。 転ばぬ先のログ取り。 ログ取りがサーバーの負担にならない限りは、好きなログを取って置いた方がいいと思います。 暇が出来た時にログを眺めたり分析する、「たまに」の作業は 重要だと思います。 例えば、httpdで、%D( リクエストを処理するのにかかった時間)等を 取っておけば、処理の重いURLを抜き出したりも出来ます。

必要最低限のログ取り設定

  1. syslogで、エラー若しくはwarning以上のファイルを一ファイルにまとめておく。 (普段はこのファイルだけ確認すればOKにしたいので) webmin等で設定すると手軽です。 設定すればrsyslogを再起動後、loggerコマンドで動作をチェックしてみましょう。

    logger -p local0.warning "test warning message for rsyslog"
    logger -p local0.info "test info message for rsyslog"
    warning messageだけ、新規作成したファイルに残っていればOKです。
    

    http://www.gadgety.net/shin/tips/unix/syslog.html 参照

  2. logrotateを変更→とりあえず古いログを圧縮することと、残す期間は4週→年単位位まで増やしておいた方が セキュリティ&後々のためです。 オプションは→ http://www.atmarkit.co.jp/flinux/rensai/linuxtips/747logrotatecmd.html これらの設定は、webminから設定すると行い易いです。上記で追加したwarning以上のログファイルは、 syslog系の(/var/log/message)と同じところに足しておいてやれば問題ないです。

  3. ログを眺めて、無駄なエラーログがあれば叩いてあげましょう。 これは、定期的に行いましょう。 ログが汚されるのは確認の手間を増やし、異常を見逃す確率が高くなります。

  4. syslogのログ形式を下記のものへ(/etc/rsyslog.conf):

    $ActionFileDefaultTemplate RSYSLOG_FileFormat
    

    でないと、ログに西暦が残らない。

logwatch(ログ監視ツール)の導入

本項の目標は、自分専用のログ収集ルールを作成することです。

これは一日一回ログを解析してメール等でレポートを行うために利用されることが 多いみたいです。他にも全ての期間のログから条件にマッチするログを抽出することも できたりするみたいです。 このページは、自分専用のログ収集ルールをlogwatchに登録する方法を 説明してくれています。

http://server-setting.info/centos/logwatch-original-log.html

ログファイルの解析をperlで書け、perl使いの管理人からすると かなり助かります。perlは正規表現を使い易いという強味があります。

元々logwatchには、様々なサービスのログを分析するスクリプトが ついてきていますが、個人のサーバー管理用とでは複雑で量が多いので 手に負えないところがあります。 ですので、収集ルールを適当に作っておきます。 のちのちは、これをカスタムしていけば、いいと思います。

今回作成した設定ファイルを記載します。上記のページを併せて参照ください。

/usr/share/logwatch/default.conf/services/all-log.conf:

# LogWatchで出力される際のタイトルを設定します。
Title = All log
# ログファイルのグループ名を設定します。
#   この名前で、.../conf/logfiles/example-log.conf が決定します。
LogFile = all-log

/usr/share/logwatch/default.conf/logfiles/all-log.conf:

Logfile = httpd/access_log
Archive = httpd/access_log-*
Archive = httpd/access.log-*.gz
Logfile = httpd/error_log
Archive = httpd/error_log-*
Archive = httpd/error.log-*.gz
Logfile = httpd/ssl_*_log
Archive = httpd/ssl_*_log-*
Archive = httpd/ssl_*.log-*.gz
Logfile = yum.log
Archive = yum.log-*
Archive = yum.log-*.gz
Logfile = munin/munin-update.log
Archive = munin/munin-update.log-*
Archive = munin/munin-update.log-*.gz
Logfile = munin/munin-graph.log
Archive = munin/munin-graph.log-*
Archive = munin/munin-graph.log-*.gz
Logfile = munin/munin-html.log
Archive = munin/munin-html.log-*
Archive = munin/munin-html.log-*.gz
Logfile = munin/munin-limits.log
Archive = munin/munin-limits.log-*
Archive = munin/munin-limits.log-*.gz
Logfile = munin-node/munin-node.log
Archive = munin-node/munin-node.log-*
Archive = munin-node/munin-node.log-*.gz
Logfile = samba/log.*
Archive = samba/log.*-*
Archive = samba/log.*-*.gz
Logfile = cron
Archive = cron-*
Archive = cron-*.gz
Logfile = maillog
Archive = maillog-*
Archive = maillog-*.gz
Logfile = messages
Archive = messages-*
Archive = messages-*.gz
Logfile = secure
Archive = secure-*
Archive = secure-*.gz
Logfile = spooler
Archive = spooler-*
Archive = spooler-*.gz
Logfile = over_warn_message
Archive = over_warn_message-*
Archive = over_warn_message-*.gz

/usr/share/logwatch/scripts/services/all-log:

#!/usr/bin/perl

# Logwatch の dates の使用宣言を行います。
use Logwatch ':dates';

# ログファイルに出力される日付フォーマットを指定します。
$sdate = TimeFilter("%Y-%m-%d");
$date1=TimeFilter("%Y/%m/%d");

print "All log was started.";
# ログファイルを1行づつ読み込み処理します。
while (defined($line = <STDIN>)) {
    # 同じ日付なら、ログ情報を出力します。
    if ($line =~ /$sdate/ || $line=~/$date1/) {
        if($line =~/error/i||$line=~/warn/i||$line=~/fail/i){
        print $line;
        }
    }
}

吐き出したいコマンドを確認。今回は1週間のレポートが欲しいので、以下:

logwatch --print --range 'between -7 days and yesterday' --detail med

日付の指定方法は、manページにもありますが、以下のコマンドで表示できます。:

logwatch --range help

メール送信スクリプト(smtps利用、言語はpython)

後オマケに、メールを送信できるようにしておきましょ。 別途に、メールアカウント持っているのでそれを利用します。 gmailでも同様の方法で利用可能なはずです。 何かしらの文章を、任意のあて先へ送付できるだけの機能があれば十分なので、 sendmailの設定は避けてpythonを利用。 パスワードを生で置いているので、アクセス権限に注意を。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import smtplib
from email.MIMEText import MIMEText
from email.Utils import formatdate

##SMTPS(SMTP over SSL)でメールを送信するプログラム。
#使用例は、echo "本文" | test.py mail_title to@example.com


#設定部分
SMTP_HOST="smtp.example.com"
in_id="some_user_id"
in_pw="some_pw"
MAIL_FROM=in_id #送信元のメールアドレス
PORT_NUM=465     #ポート番号


#メール内容の受け取り。本文は標準入力で受け取る。
SUBJECT=sys.argv[1]
MAIL_TO=sys.argv[2]
BODY=""
for line in sys.stdin:
    BODY += line


#処理。SSL認証のサーバーを利用するためSMTP_SSLオブジェクトを利用
msg = MIMEText(BODY)
msg['Subject'] = SUBJECT
msg['From'] = MAIL_FROM
msg['To'] = MAIL_TO
msg['Date'] = formatdate()

s = smtplib.SMTP_SSL(SMTP_HOST,PORT_NUM)
s.login(in_id,in_pw)
s.sendmail(MAIL_FROM, [MAIL_TO], msg.as_string())
s.close()

他にもmailxを利用するという手もあります。manページは

http://heirloom.sourceforge.net/mailx/mailx.1.html

読みこなすのはしんどいので、以下の設定を参考。

http://serverfault.com/questions/498588/smtp-gmail-com-from-bash-gives-error-in-certificate-peers-certificate-issuer

一応下記に残します。sshキーの扱いが難解です。:

# Create a certificate directory
$ mkdir certs
# Create a new database in the certs dir
$ certutil -N -d certs
# Fetch the certificate from Gmail, saving in the text file GMAILCERT
$ echo -n | openssl s_client -connect smtp.gmail.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > GMAILCERT
# Import the new cert file into the new database in the new dir
$ certutil -A -n "Google Internet Authority" -t "C,," -d certs -i GMAILCERT
# Double Check
$ certutil -L -d certs

~/.mailrc:

#メールサーバ
set smtp=smtps://********:465
#認証方式
set smtp-auth=login
#SMTPユーザ名
set smtp-auth-user=*************
#SMTPパスワード
set smtp-auth-password=*************
set ssl-verify=ignore
set nss-config-dir=~/certs
set from="**************"

以上の設定でメールが送信できるはず。:

echo test message | mailx -s "testtitle" "admin@helloaworld.com" 2>test.log

Logwatchのメール設定

現状Logwatchのメール送信機能は、私自身設定が完了していません。とりあえずの項になりますが、以下のように設定しようとしています。

logwatchのメール送信機能はsendmailを前提にしているようです。今回はsendmailを利用しないので、少し細工が必要です。 と言っても、logwatchはそれほど作りこまれていないようです。/etc/cron.daily/0logwatchを見れば結構単純に動いているのが分かると思います。

と言うわけで、

/etc/cron.daily/0logwatchのlogwatchの行を以下に置き換え:

logwatch --print |mailx -s "Logwatch Daily Report" admin@****.com

週次のものを設定するため、0logwatchを/etc/cron.weekly/にコピーして、logwatchの行を以下に置き換え:

logwatch --print --range 'between -7 days and yesterday' --detail med | mailx -s "Logwatch Weekly Report" admin@****.com

0logwatchを実行して、メールが届くか確認。

最後に

少し、冗長な部分が多かったり、まとめ方が雑なところがありました。 またサーバーを立てる等の機会があったら、整理して記事に起こし直せればです。