お疲れ様です!
キャスレーコンサルティングのSI(システム・インテグレーション)部の栗田です。

ここ最近、何となくウェブサーバーを立ててみたいと思い、今回のテーマを思いつきました。
(ざっくりすぎですが…。)

ただ立てるだけでは味気なく思い、方向音痴な自分へのプレゼントも兼ねて、
「今回は地図上の最短ルートを検索するサイトも作成してみよう!」
と思います。

map
(こんな感じのよくあるものです。)

「前編:サーバー構築編」では、Webサーバー構築からpgRouting用の地図データのインポートまでの説明をさせて頂きたいと思います。

環境は、
OS:Ubuntu16.04 LTS
DB:postgresql9.5、PostGIS、pgRouting
言語:PHP7.0
といった内容の構築となります。
(サーバー接続用のWindows端末も必要となります。)

※Ubuntuのインストール手順は省略させて頂きます。既にインストール済の前提で進めさせて頂ければと思います。

前準備

1. サーバー接続用のWindows端末を用意し、TeraTermをインストールして下さい。
2. TeraTermでサーバーに接続し、下記のコマンドを実行します。
パッケージのリストをサーバーから入手したり、インストール済のパッケージの最新化などを行います。

sudo apt-get update
sudo apt-get check
sudo apt-get -s upgrade
sudo apt-get upgrade

テキストエディタをインストールします。

sudo apt-get install vim

これで前準備はokです。

セキュリティ対策

今時は色々な輩がここぞとばかりにサーバーを乗っ取ろうと試みてくるようです。
怖い世の中ですね…。
それではセキュリティ面の設定に関する説明をさせて頂きます。

♦SSH接続の設定
SSHで接続する際は鍵認証にしたいと思います。ペアとなる鍵がなければSSH接続できない仕組みとなります。

1. TeraTermを起動し、「新しい接続」ダイアログを閉じます。
2. 設定(S) → SSH鍵生成(N)で下記ダイアログを表示します。

tera1

3.「生成」ボタンをクリックします。
4.「鍵のパスフレーズ」を入力後に「公開鍵の保存」「秘密鍵の保存」をクリックします。
5. TeraTermでサーバーに接続し、TeraTermに公開鍵のファイルをドラッグドロップします。
6.「SCP」ボタンをクリックするとホームディレクトリにアップロードされます。

tera2
7. TeraTermで以下のコマンドを実行して、鍵を登録します。

cd ~
mkdir .ssh
chmod 700 .ssh
cat id_rsa.pub > .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
rm -f id_rsa.pub

8. Rootになり、以下のファイルを編集します。

sudo su -
vim /etc/ssh/sshd_config

【変更箇所】

# Port22を開放したままは危険なので、違うポート番号にして下さい。(1024以上が良いと思います。)
#Port22 → コメントを外し、Port12345 に変更(もちろん12345以外でも可能です)

# rootユーザでのログインを無効にして下さい。
#PermitRootLogin yes → コメントを外し、PermitRootLogin no に変更

# パスワード認証を無効にして鍵認証にして下さい。
PasswordAuthentication yes → PasswordAuthentication no に変更

# X11Protcolを遮断して下さい。
#X11Forwarding yes
#X11DisplayOffset 10
X11Forwarding no

9. SSHをリロードして設定を反映して下さい。

service ssh reload

♦iptablesの設定
決められたIPアドレス、ポートの接続のみを許可します。

1.適当なディレクトリを作成し、iptables設定用のスクリプトファイルを作成します。
スクリプトファイルは/etc/network/iptables/set_iptablesで新規作成します。

sudo mkdir /etc/network/iptables/
sudo vim /etc/network/iptables/set_iptables

【ファイルの内容】
ファイルの内容は状況によって変更して下さい。

/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD DROP
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT

#下記のようなプライベートIPアドレスはアクセス禁止
/sbin/iptables -A INPUT -s 10.0.0.0/8 -j DROP
/sbin/iptables -A INPUT -s 172.16.0.0/12 -j DROP
/sbin/iptables -A INPUT -s 192.168.0.0/16 -j DROP

#PING応答許可
/sbin/iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

#下記ポート有効(12345は♦SSH接続の設定の8.で決めたポート番号です)
/sbin/iptables -A INPUT -p tcp --dport 12345 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 5432 -j ACCEPT

/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables-save > /etc/network/iptables/iptables.db

2. 作成したファイルに実行権限を与えて実行して下さい。実行するとiptables.dbが作成されます。

sudo chmod +x /etc/network/iptables/set_iptables
sudo /etc/network/iptables/set_iptables
ls /etc/network/iptables/

3. ネットワークの起動時にiptablesの設定を反映するシェルスクリプトを作成します。
/etc/network/if-pre-up.d/ディレクトリにシェルスクリプトファイルを設置すると、ネットワーク起動時に自動でスクリプトを実行します。
シェルスクリプトファイルは/etc/network/if-pre-up.d/load_iptablesで新規作成して下さい。

sudo vim /etc/network/if-pre-up.d/load_iptables

【ファイルの内容】

#!/bin/sh
/sbin/iptables-restore < /etc/network/iptables/iptables.db

4. 実行権限を付与します。すぐに反映したい場合はシェルスクリプトを実行して下さい。

sudo chmod +x /etc/network/if-pre-up.d/load_iptables
sudo /etc/network/if-pre-up.d/load_iptables

次は、Webサーバーの導入に入りたいと思います。

ApacheとPHPを導入

1. Apacheをインストールします。

sudo apt-get install apache2

2. PHPと共に、Apacheとpostgresqlで使用するためのモジュールをインストールします。

sudo apt install -y php
sudo apt install libapache2-mod-php
sudo apt-get install php7.0-pgsql

3. /var/www/htmlにinfo.phpというファイルを作成します。
【ファイルの内容】

<?php
 phpinfo();
?>

4. Apacheを再起動します。

sudo systemctl restart apache2.service

5. Windows端末もしくはスマホなどから、http://(サーバーのIPアドレス)でアクセスし、
「It Works!」が表示されればApacheが正常に起動しています。
apache1

6. Windows端末もしくはスマホなどから、http://(サーバーのIPアドレス)/info.phpでアクセスし、
「phpinfo」が表示されればPHPが正常に起動しています。
php1

postgresqlを導入

次にルート検索の肝となるデータベース(postgresql)のインストールを行いたいと思います。
あと絶対に必要ではありませんが、Windows端末にpgAdminをインストールしておくと便利ですので、ご検討下さい。

1. pgRouting絡みのパッケージをインストールするために、aptのリポジトリに以下を追加します。
あとはadd-apt-repositoryを使用できるようにします。

sudo apt-get install apt-file
sudo apt-file update
sudo apt-file search add-apt-repository
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:georepublic/pgrouting-unstable
sudo apt-get update

2. postgresqlとPostGISをインストールします。

sudo apt-get install postgresql postgis proj-bin gdal-bin
sudo /etc/init.d/postgresql start

3. pgRoutingとOpenStreetMapのデータをpgRoutingで使うためのパッケージをインストールします。

sudo apt-get install postgresql-9.5-pgrouting
sudo apt-get install osm2pgrouting

4. postgresユーザのパスワードを設定して下さい。

sudo passwd postgres

5. OpenStreetMap用テーブルを作成します。

sudo -u postgres createdb --encoding=UTF8 osm;

6. posgtesユーザーでログインし、PostGISとpgRouting拡張を適用します。

su - postgres
psql --username=postgres --dbname=osm -c "CREATE EXTENSION postgis;"
psql --username=postgres --dbname=osm -c "CREATE EXTENSION pgrouting;"

7. postgresqlの設定を変更します。まずはpostgresql.confを変更し、外部からpostgreSQLに接続できるようにします。

sudo vim /etc/postgresql/9.5/main/postgresql.conf

【変更箇所】

#listen_addresses = 'localhost' を listen_addresses = '*'に変更して下さい。

7. 次にpg_hba.confを変更し、こちらも外部からpostgreSQLに接続できるようにします。

sudo vim /etc/postgresql/9.5/main/pg_hba.conf

【変更箇所】

host all all 0.0.0.0/0 trust の行を追加します。
local all postgres peer を local all postgres trust に変更します。

8. 変更後にpostgresqlを再起動します。

sudo /etc/init.d/postgresql start

openStreetMapデータの取り込み

1. http://download.geofabrik.de/に日本の部分を効率よく切り取ってくれたデータがありましたので、これを利用します。
OSMの地図データ(XML)を圧縮したデータがpbfデータとなります。ホームディレクトリにダウンロードします。

cd ~
wget -c http://download.geofabrik.de/asia/japan-latest.osm.pbf

2. *.pbfを*.osm(xml)に変換します。変換後はサイズが25GBほどになりますので、ご注意下さい。

osmconvert japan-latest.osm.pbf > map.osm

3. postgresqlにOSMデータをインポートします。
ただし物凄く時間がかかってしまい、ここから先は後編で説明させて頂きたいと思います。
コマンドとしては以下で実行できると思います。

osm2pgrouting -f map.osm -c /usr/share/osm2pgrouting/mapconfig.xml -d osm -U postgres --clean

※物凄くスワップ領域を使うので、途中でOOMKillerに”Killed”される可能性があります。
その場合はスワップ領域を増やして下さい。とりあえず一時的に20GBまで増やしてしまいました…。

# 管理者権限になる
sudo su -

# スワップ用フォルダの作成
mkdir /var/swap

# 2Gのスワップ用のファイル作成
dd if=/dev/zero of=/var/swap/swap0 bs=1M count=20480

# パーミッションの設定
chmod 600 /var/swap/swap0

# スワップ割り当て
mkswap /var/swap/swap0
swapon /var/swap/swap0

スワップ領域を削除する場合は以下のコマンドを実行して下さい。

# スワップ停止
swapoff /var/swap/swap0

#スワップ用ファイルの削除
rm /var/swap/swap0

最後に

次回はフロント側(JQuery+Ajax、ハイブリッドアプリ)もしくはAndroidアプリ(LocationManagerなどでGPSを使用するなど)で、現在位置から最も近いルートをサーバーから取得しながら、目的地へ向かってみるなど出来たら良いな…と考えております。
地図を扱うと世界旅行した気分になれますね(笑)
発想次第では色々な可能性を秘めていると思いますので、地図に関連する開発も勉強して頂けますと夢が膨らむと思います!

以上となります。
最後まで読んで頂き、大変感謝です!



  • Profile
    キャスレーコンサルティングの技術ブログです。
    当社エンジニアが技術面でのTips、技術系イベント等についてご紹介いたします。
  • CSV社長ブログ
  • チーム・キャスレーブログ