- 投稿日:2020-09-17T22:48:57+09:00
Raspberry PiでApache2.4+PHP7.4をソースコンパイルしてWebサーバー構築 - 3.MySQLを使う
前提と準備
Linuxサーバー構築の記事
- Sambaでファイルサーバー構築(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)
- LinuxでApache2.4+PHP7.4をソースコンパイル - 1.Apache導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 2.PHP導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 3.MySQL導入 /【Raspberry Pi:この記事】
- LinuxでApache2.4+PHP7.4 - 4.セキュリティ(chownとfirewalld)
- LinuxでIPsecゲートウェイをVPN構築 - 1.StrongSwan導入 /【Ubuntu 20.04+Raspberry Pi】
- LinuxでIPsecゲートウェイをVPN構築 - 2.VPNへの接続確認 /【Ubuntu 20.04+Raspberry Pi】
前回はApache2.4にPHP7.4をソースコンパイルでWebアプリ環境を構築しましたが、残念なことに、標準でRaspberry Pi向けのLinuxは、MySQLをサポートしておらず、RPMやAPTのリポジトリにも存在しません。ですが、外部MySQLサーバーを接続することは可能です。
簡単なためにWebサーバーと一体でデータベースのMySQLを構築したいと思っても、Raspberry Piの場合はそうにはいかず、たとえインストールできたとしても、microSDの書き込みには非常に不向きなので、今後ラズパイがM.2 SSD相当のストレージに対応しているラインアップを展開すれば、MySQLのサポートも可能かもしれないですが…(✿・ω・)それまではとにかくMySQLを無理にラズパイに導入してストレージにエラーが出ても、またもや本末転倒だしなぁ…
環境
- Webサーバープログラム:Apache 2.4.46 + PHP 7.4.10
- クライアント:Windows10 Pro
- サーバーのアーキテクチャ:Raspberry Pi 3B+(armv8搭載) Linuxのディストリビューション:openSUSE 15.1 Leap(64bit) / Raspberry Pi OS 2020.08版(32bit)
- 別途用意する端末:MySQLサーバー(私の場合はCentOS 8.1にMySQL 8.0を構築しました)
前提
- ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
- openSUSEではファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)。ラズパイのRaspberry Pi OSでは、firewalldについて、IPv6周りの連動が糞だったので、Debian系標準のufwを使用することにしました。
- 前回の記事のApache+PHP導入を完了していること
サーバー条件
IPアドレス
- クライアント:192.168.1.11
- Webサーバー:192.168.1.22 (前回まで192.168.1.18でしたが、DBで使われていたので、ラズパイのIPアドレスを変更しました)
- データベースサーバー:192.168.1.18 (ラズパイで使ってたのと重複していたので、ラズパイの方を192.168.1.22に変更しました)
- 所属ネットワークセグメント:192.168.1.0/24
パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)
- zlib-1.2.11.tar.gz
- apr-1.7.0.tar.gz
- apr-util-1.6.1.tar.gz
- httpd-2.4.46.tar.gz
- php-7.4.10.tar.gz
それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。
ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。
作業手順
MySQLクライアントの導入
MariaDBクライアントツールのインストール
MySQLコマンドを管理するクライアントに、「MySQL」と明確なパッケージは、ラズパイ向けLinuxには含まれていないため、MariaDBクライアントをインストールしました。
openSUSE15.1(RaspberryPi)# zypper -n install mariadb-clientRaspberryPiOS(2020.08)# apt-get -y install mariadb-clientこれで、MySQLコマンドがラズパイから使えるようになりました。
MySQLサーバーでの準備
サーバーでのユーザーとデータベース
今回は、CentOS 8.1にMySQLサーバーを構築した仮想マシンを使うので、この記事で構築したデータベースを使ってみます。
- データベース名:manutest
- テストユーザー名:test
- テストユーザーパスワード:test1
- 文字コード:UTF-8
- MySQLサーバーのIPアドレス:192.168.1.18
なおパスワードは私的都合で「test0」から「test1」に変えました。
MySQLサーバー上での準備
最初にMySQLが他の端末からアクセスできるように、MySQLサーバーでいろいろ準備します。
MySQLのrootでログインします。
MySQLサーバー(CentOS8.1)[このコマンドに限り、MySQLサーバー上で実施するものです] # mysql -u root -p Enter password: ← MySQLのrootパスワードを入力 mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | manutest | ← 作成したデータベースが表示される | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec) mysql> CREATE USER 'test'@'192.168.1.22' IDENTIFIED BY 'test1'; ↑ ラズパイのIPアドレス「192.168.1.22」向けのユーザー名「test」を作成する mysql> GRANT ALL ON manutest.* TO 'test'@'192.168.1.22'; ↑ データベース「manutest」に対して「test」が「192.168.1.22」から全機能を使えるエラーがなく「Query OK, 0 rows affected」が表示されれば、データベースとユーザーは作成完了。
つまり、MySQLとApacheが同一のサーバーマシンにある場合は「localhost」で済んだが、今回はラズパイ→MySQLサーバーからという、他のサーバーにアクセスするので、以下のように、ユーザー名+@マーク+ホスト、というように、
CREATE USER '<ユーザー名>'@'<ラズパイのホスト>' IDENTIFIED BY '<パスワード>';
GRANT ALL ON <データベース名>.* TO '<ユーザー名>'@'<ラズパイのホスト>';というような指定が必要だということですね(˶ ・ᴗ・ )੭
MySQLサーバーでは、CentOSでfirewalldの開放も必要でしたね(˶ ・ᴗ・ )੭**
MySQLサーバー(CentOS8.1)[このコマンドに限り、MySQLサーバー上で実施するものです] # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept' # firewall-cmd --reloadMySQLのポートは3306/TCPなので、そのポートを開放することで、MySQLサーバーにPHPなんかがアクセスできるということ…
Raspberry Pi→MySQLサーバーに接続できるか確認
MySQLサーバーでの作業はここまで。
では、Raspberry Piに戻って、MySQLを使えるか試します。mysqlコマンドで「-h」オプションでホストを指定できますRaspberryPi(ラズパイOS・openSUSE15.1)# mysql -h 192.168.1.18 -u test -p Enter password: ← パスワード「test1」を入れる (中略) mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | manutest | ← 作成したデータベースが表示されれば成功 +--------------------+ 2 rows in set (0.00 sec)ちゃんとテーブルの中身も参照できるまでに至りました!!( ˶˙ᵕ˙˶ )
PHPからMySQLサーバーを使う
PHPからMySQLの接続を確認
MySQLサーバーには、前回仮想マシンのCentOSで構築したように、テスト用テーブルを使ってみます。
テーブル名:testtb
id name memo 型 INT VARCHAR(64) VARCHAR(256) 必須属性 PRIMARY KEY NOT NULL 初期値NULL その他属性 AUTO_INCREMENT - - まずはテーブルを使う前に、PHPでMySQLに接続できるかちゃんと確かめないといけません(*˘ᗜ˘*;)
接続確認ページを作ります
# cd ~ # vi connect.phpconnect.php<?php $dsn = 'mysql:dbname=manutest; host=192.168.1.18'; $usr = 'test'; $pass = 'test1'; try { $db = new PDO($dsn, $usr, $pass); print 'Connection successful.'; $db = NULL; } catch(PDOException $e){ die('Connect error : '.$e->getMessage()); } ?>これを、Apache導入時にインストールした先のWebページの格納場所 /usr/local/apache2/htdocs/に移動します。
# mv connect.php /usr/local/apache2/htdocs/PHPページの配置なので、特にApacheを再起動することは不要なので、https://[LinuxサーバーのIPアドレス]/connect.php と入力して確認。192.168.1.18はMySQLサーバーで使われていて、ラズパイLinuxサーバーのIPアドレスは192.168.1.22なので、ブラウザでhttps:~の後に、192.168.1.22/connect.phpをURLを入力してアクセス。
PHPからMySQLにデータを登録できるかを確認
続いて、いよいよデータが登録できるかを確認します。
再びWebページを作ります。まずは登録フォームから。
# vi test_form.htmltest_form.html<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>テストページ - Test page</title> </head> <body> <form method="POST" action="test_form.php"> <input type="text" name="name" /> <input type="text" name="memo" /> <input type="submit" value="Submit" /> </form> </body> </html>続いて、フォームから受け取ったデータをMySQLデータベースへ追加するPHPを作成
# vi test_form.phptest_form.php<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>テスト入力 - Test insert</title> </head> <body> <?php function getDb(){ $dsn = 'mysql:dbname=manutest; host=192.168.1.18'; $usr = 'test'; $pass = 'test1'; try { $db = new PDO($dsn, $usr, $pass); $db->exec('SET NAMES utf8'); } catch(PDOException $e){ die('Connect error : '.$e->getMessage()); } return $db; } try { $db = getDb(); $stt = $db->prepare('INSERT INTO testtb (name, memo) VALUES (:one, :two)'); $stt->bindValue(':one', $_POST['name']); $stt->bindValue(':two', $_POST['memo']); $stt->execute(); print $_POST['name'].' - '.$_POST['memo'].' : Insert OK.'; $stt = $db->query("SELECT * FROM testtb"); ?> <table border="1"> <?php while($row = $stt->fetch(PDO::FETCH_ASSOC)){ ?> <tr> <td><?php print $row['name']; ?></td> <td><?php print $row['memo']; ?></td> </tr> <?php } ?> </table> <?php $db = NULL; } catch(PDOException $e){ die('Process error : '.$e->getMesssage()); } ?> </body> </html>上記2ファイルをApacheのWebページデータの場所へ。
# mv test_form.* /usr/local/apache2/htdocs/では、ブラウザでhttps://[IPアドレス]/test_form.htmlにアクセスして、データを登録してみると…
これも登録成功しました!(˶ ・ᴗ・ )੭⚐⚑
PCより非力かつストレージもmicroSDというDBの読み書きに不向きなラズパイだからこそ、外部のDB用のサーバーと一緒に外部アクセスすることで、ラズパイもDBを扱えることが実感できた瞬間ですあとがき
Raspberry PiはPCと比べて非力でストレージもmicroSDなので、PCと全く同じようなサーバー構築だと、メモリ不足やデータベースの非対応やらで比較的道のりは険しい一方で、省電力という恩恵ならではのメリットもまたあるということを、今回の構築を通して感銘したな…とも思う(♥´꒳`*)
今後と次回
PHPによるWebアプリサーバー構築のほかにも、Java(OpenJDK)によるWebアプリサーバーについても、構築に触れてみたい
- 投稿日:2020-09-17T20:07:27+09:00
Raspberry PiでApache2.4+PHP7.4をソースコンパイルしてWebサーバー構築 - 2.PHP導入編
前提と準備
Linuxサーバー構築の記事
- Sambaでファイルサーバー構築(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)
- LinuxでApache2.4+PHP7.4をソースコンパイル - 1.Apache導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 2.PHP導入 /【Raspberry Pi:この記事】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 3.MySQL導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4 - 4.セキュリティ(chownとfirewalld)
- LinuxでIPsecゲートウェイをVPN構築 - 1.StrongSwan導入 /【Ubuntu 20.04+Raspberry Pi】
- LinuxでIPsecゲートウェイをVPN構築 - 2.VPNへの接続確認 /【Ubuntu 20.04+Raspberry Pi】
前回はApache httpd 2.4.46をソースコンパイルでRaspberry Piに構築しましたが、今回は、前回に引き続き、ApacheにWebアプリサーバーの基幹であるPHP 7.4をソースコンパイルで導入します(⑅•ᴗ•⑅)
環境
- Webサーバープログラム:Apache 2.4.46 + PHP 7.4.10(ソースコンパイル)
- クライアント:Windows10 Pro
- サーバーのアーキテクチャ:Raspberry Pi 3B+(armv8搭載) Linuxのディストリビューション:openSUSE 15.1 Leap(64bit) / Raspberry Pi OS 2020.08版(32bit)
前提
- ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
- openSUSEではファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)。ラズパイのRaspberry Pi OSでは、firewalldについて、IPv6周りの連動が糞だったので、Debian系標準のufwを使用することにしました。
- 前回の記事のApache導入を完了していること(動作が確認できて、Webサーバーとして構築されていること)
サーバー条件
IPアドレス
パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)
- zlib-1.2.11.tar.gz
- apr-1.7.0.tar.gz
- apr-util-1.6.1.tar.gz
- httpd-2.4.46.tar.gz
- php-7.4.10.tar.gz
それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。
ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。
作業手順
PHPのインストール
PHPのソースコンパイルに必要なライブラリを導入
openSUSE15.1(RaspberryPi)# zypper -n install libxml2-tools libxml2-devel sqlite3-devel oniguruma-develRaspberryPiOS(2020.08)# apt-get -y install libxml2 libxml2-dev libsqlite3-dev libonig-devPHP7.3までは、SQLiteと鬼車のライブラリを使わなくてもマルチバイト文字列を扱うようインストールができたのですが、PHP7.4ではソースコンパイルで必須となりました。
PHPのソースコンパイル(実際swap仮想メモリ不足で強制終了しハマった)
コンパイルには30~40分前後かかる見込みです。Apacheより規模が大きいので、コンパイル中はコーヒー1杯で休憩をはさんだほうがいいかもしれません(*˘︶˘*).。.:*♡
# cd [php-7.4.10.tar.gzが置いてあるディレクトリ] # tar xvzf php-7.4.10.tar.gz # cd php-7.4.10/ # ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysqli --with-pdo-mysql --enable-mbregex --enable-mbstring # make # make test
- MySQLはPDOを有効にします
- マルチバイト文字列を有効にします
「make」「make test」が時間がかかるコマンドです。
途中でエラーがなければコンパイル完了ですが、そこでRaspberry Pi OSのほうで問題発生。RaspberryPiOS(2020.08)# make /bin/bash /home/admin/php-7.4.10/libtool --silent --preserve-dup-deps --mode=compile cc -I/home/admin/php-7.4.10/ext/fileinfo/libmagic -Iext/fileinfo/ -I/home/admin/php-7.4.10/ext/fileinfo/ -DPHP_ATOM_INC -I/home/admin/php-7.4.10/include -I/home/admin/php-7.4.10/main -I/home/admin/php-7.4.10 -I/home/admin/php-7.4.10/ext/date/lib -I/usr/include/libxml2 -I/home/admin/php-7.4.10/ext/mbstring/libmbfl -I/home/admin/php-7.4.10/ext/mbstring/libmbfl/mbfl -I/usr/local/include -I/home/admin/php-7.4.10/TSRM -I/home/admin/php-7.4.10/Zend -D_REENTRANT -pthread -I/usr/include -g -O2 -fvisibility=hidden -pthread -Wall -Wno-strict-aliasing -DZTS -DZEND_SIGNALS -c /home/admin/php-7.4.10/ext/fileinfo/libmagic/apprentice.c -o ext/fileinfo/libmagic/apprentice.lo cc: fatal error: 強制終了 signal terminated program cc1 compilation terminated. make: *** [Makefile:738: ext/fileinfo/libmagic/apprentice.lo] エラー 1こんなふうにmake中で強制終了してしまった(´•ω•̥`)
PHPは相当の処理の多さでビルドするので、Raspberry Pi OSだけなぜ…と思いつつ、メモリの空き容量を調べてみたら…RaspberryPiOS(2020.08)# free total used free shared buff/cache available Mem: 948072 389256 367752 99504 191064 394740 Swap: 102396 102256 140Raspberry Pi OSではたったの100MBしかswap領域がなかったことに気が付いて、空きが1MBだけ…(openSUSEはRaspberry Piでも400MBはあった)
なので、swap領域を増やして仮想メモリを増やすことにした。Raspberry Pi OSでは、swapはパーテーションではなくdphys-swapfileで定義される
- 参照:パイ・スワップの増量
RaspberryPiOS(2020.08)# vi /etc/dphys-swapfile CONF_SWAPSIZE=100 ← 増量する CONF_SWAPFACTOR=2 ← 倍率を設定する # reboot私の場合は200MBに増量して、倍率を2に設定しました。
再起動して再ビルドし、今度こそうまく成功しました!!
【でも実際は再起動したことによってビルドがうまくいったっぽい】しかしさらなる問題が発生した。
今度は「make test」でSegmentation Faultとなってしまう事象が発生している。ビルドは成功したはずなのに、テストがセグメンテーション違反(Windowsでいうアプリケーションエラーと呼ばれている)でクラッシュする事象が発生。。。テストツールに問題があるのか、ビルドしたモジュールに問題があるのか、今回のところはとりあえずPHPを動かして調べてみることにするので、テストはいったん保留。
PHPのインストール
コンパイルが完了したら、インストールします。
# make install Installing PHP SAPI module: apache2handler /usr/local/apache2/build/instdso.sh SH_LIBTOOL='/opt/apr-1.7.0/build-1/libtool' libphp7.la /usr/local/apache2/modules /opt/apr-1.7.0/build-1/libtool --mode=install install libphp7.la /usr/local/apache2/modules/ libtool: install: install .libs/libphp7.so /usr/local/apache2/modules/libphp7.so libtool: install: install .libs/libphp7.lai /usr/local/apache2/modules/libphp7.la libtool: warning: remember to run 'libtool --finish /home/admin/php-7.4.6/libs' chmod 755 /usr/local/apache2/modules/libphp7.so [activating module `php7' in /usr/local/apache2/conf/httpd.conf] Installing shared extensions: /usr/local/lib/php/extensions/no-debug-zts-20190902/ Installing PHP CLI binary: /usr/local/bin/ Installing PHP CLI man page: /usr/local/php/man/man1/ Installing phpdbg binary: /usr/local/bin/ Installing phpdbg man page: /usr/local/php/man/man1/ Installing PHP CGI binary: /usr/local/bin/ Installing PHP CGI man page: /usr/local/php/man/man1/ Installing build environment: /usr/local/lib/php/build/ Installing header files: /usr/local/include/php/ Installing helper programs: /usr/local/bin/ program: phpize program: php-config Installing man pages: /usr/local/php/man/man1/ page: phpize.1 page: php-config.1 /home/admin/php-7.4.6/build/shtool install -c ext/phar/phar.phar /usr/local/bin ln -s -f phar.phar /usr/local/bin/phar Installing PDO headers: /usr/local/include/php/ext/pdo/PHPのライブラリのいくつかは「/usr/local/include/php/」「/usr/local/lib/php/」のように、用途に応じて複数の配置場所へ配置されます。しかも今回PHP 7.4.10は、ラズパイのopenSUSEでも「/usr/local/lib64/php/」に配置されるのではなく、他のディストリビューションと同じ配置になったんです。なぜだかは知らないが、とりあえずPHP 7.4.10+openSUSE 15.1をラズパイで実装すると、lib64に配置されずlibディレクトリに配置されることがわかったんです。
また、この時点で、PHPのDLL(ダイナミックリンクライブラリ、外部拡張アプリケーションに該当する)は自動的にApacheのフォルダに配備されます。
次に、PHPの環境設定ファイルのコピーを行います。
まずはphp.iniをPHPのライブラリフォルダ/usr/local/lib(openSUSEも含む)/にコピーします。# cp php.ini-development /usr/local/lib/php.ini # ls -l /usr/local/lib 合計 328 -rw-r--r-- 1 root root 144402 6月 24 12:34 libz.a lrwxrwxrwx 1 root root 14 6月 24 12:34 libz.so -> libz.so.1.2.11 lrwxrwxrwx 1 root root 14 6月 24 12:34 libz.so.1 -> libz.so.1.2.11 -rwxr-xr-x 1 root root 113656 6月 24 12:34 libz.so.1.2.11 drwxr-xr-x 4 root root 37 6月 24 16:19 php -rw-r--r-- 1 root root 72278 6月 24 16:21 php.ini drwxr-xr-x 2 root root 21 6月 24 12:34 pkgconfigApache側の設定
Apacheで、PHPファイルが認識できるようにする必要があるので編集します。PHPのDLLは、PHPインストール時にhttpd.confで自動的に書き込まれるので追加不要です。httpd.conf側でやるべきことは、PHPのMIMEタイプがApacheで認識されればよいのです。
# vi /usr/local/apache2/conf/httpd.conf/usr/local/apache2/conf/httpd.conf… <IfModule dir_module> DirectoryIndex index.html ← 「index.php」を追加 </IfModule> … <IfModule mime_module> AddType application/x-compress .Z AddType application/x-gzip .gz .tgz … AddType application/x-httpd-php .php ← この行を追加 </IfModule> …PHPの環境設定
PHPの文字コードや参照ライブラリの設定を変えます。
# vi /usr/local/lib/php.iniphp.ini# 内容が長いので、一部修正するもののみ、修正後のもののみを記載します。セミコロン「;」は外します。「;」外すだけの行も含めて記載されています output_buffering = On default_charset = "UTF-8" include_path = ".:/usr/local/include/php:/usr/local/lib/php" extension_dir = "/usr/local/include/php/ext" date.timezone = Asia/Tokyo mbstring.language = Japanese mbstring.encoding_translation = Off mbstring.detect_order = UTF-8, SJIS, EUC-JP, JIS, ASCII mbstring.substitute_character = nonePHPの動作確認
PHP確認用のページ
まずは確認用のPHPページを作ります。
# vi /usr/local/apache2/htdocs/phpi.phpphpi.php<?php phpinfo(); ?>なぜPHPファイルを/usr/local/apache2/htdocs/に配置する??って聞かれますが、Apacheをソースコンパイルでインストールすると、Webページデータの格納フォルダは「/usr/local/apache2/htdocs/」がデフォルトだからです。まぁ、httpd.confで格納先を変更できますが、今回はそれは割愛します。
Apacheの再起動
# systemctl stop httpd # systemctl start httpd # systemctl status httpd再起動しないとPHPのモジュールをロードした状態でApacheが動作しないので、一度止めてから、再スタートします。その後、statusで起動していることを確認します。
上の画像は仮想マシンのものですが、Raspberry Piでも同じようなphpinfoが表示されたので、PHPは使えるようになりました(*˘ᗜ˘*)
…ただ単に画像の用意が面倒だからやってないだけなんで。。。次回
MySQLに接続して、PHPのWebアプリサーバーがデータベースを利用できるようにします。ラズパイではMySQLはサポートされていないので、レポジトリから直接簡単インストールすることはできず、インストールしたとしても、microSDの書き込み寿命を縮めるだけなので、次回はMySQLサーバーに接続できるかを検証します。
- 投稿日:2020-09-17T19:37:30+09:00
Raspberry PiでApache2.4+PHP7.4をソースコンパイルしてWebサーバー構築 - 1.Apache導入編
前提と準備
Linuxサーバー構築の記事
- Sambaでファイルサーバー構築(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)
- LinuxでApache2.4+PHP7.4をソースコンパイル - 1.Apache導入 /【Raspberry Pi:この記事】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 2.PHP導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 3.MySQL導入/【Raspberry Pi】
- LinuxでApache2.4+PHP7.4 - 4.セキュリティ(chownとfirewalld)
- LinuxでIPsecゲートウェイをVPN構築 - 1.StrongSwan導入 /【Ubuntu 20.04+Raspberry Pi】
- LinuxでIPsecゲートウェイをVPN構築 - 2.VPNへの接続確認 /【Ubuntu 20.04+Raspberry Pi】
いつものPCやHyper-Vといった仮想マシンなど、x64向けのWebサーバー構築を前回は行っていましたが、今回はPCや仮想マシンではなく、Raspberry PiにApacheでWebサーバーで構築します(⑅•ᴗ•⑅)
ソースコードでコンパイルする意味
Apacheをどのディストリビューションでも同じように設定しやすいし、必要なバージョンを用意できるからです(パッケージの標準コマンドだけだと、そのディストリビューションのバージョンで変動する)。
しかし全部のパッケージをソースコンパイルすると、その大本のライブラリを全部探し回ることになるので、ApacheやPHPなど、どうしても固定して稼働したいものに限って、ソースコンパイルし、makeに必要なものについては、dnfやaptなどの標準パッケージコマンドで対応しています
環境
- Webサーバープログラム:Apache 2.4.46(ソースコンパイル)
- クライアント:Windows10 Pro
- サーバーのアーキテクチャ:Raspberry Pi 3B+(armv8搭載) Linuxのディストリビューション:openSUSE 15.1 Leap(64bit) / Raspberry Pi OS 2020.08版(32bit)
前提
- OSは最小限のインストール。また、最新の状態でOSをアップデートしていること
- ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
- openSUSEではファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)。ラズパイのRaspberry Pi OSでは、firewalldについて、IPv6周りの連動が糞だったので、Debian系標準のufwを使用することにしました。
サーバー条件
IPアドレス
パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)
- zlib-1.2.11.tar.gz
- apr-1.7.0.tar.gz
- apr-util-1.6.1.tar.gz
- httpd-2.4.46.tar.gz
- php-7.4.10.tar.gz
それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。
ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。
作業手順
準備
makeやcmake、パッケージ解凍機能のインストール
openSUSE15.1(RaspberryPi)# zypper -n install make cmake tar bzip2RaspberryPiOS(2020.08)# apt-get -y install make cmake tar bzip2GCCとC++コンパイラのインストール
openSUSE15.1(RaspberryPi)# zypper -n install gcc gcc-c++RaspberryPiOS(2020.08)# apt-get -y install gcc build-essentialzlibのソースインストール
zlibの配置場所はデフォルトのまま変えないでインストールしました。
# cd [zlibの書庫ファイルが置いてあるディレクトリ] # tar zxvf zlib-1.2.11.tar.gz # cd zlib-1.2.11/ # ./configure # make # make installApacheをコンパイルするために必要なパッケージをディストリビューション標準パッケージコマンドでインストール
PerlやSSLのライブラリなどをインストールすることで、Apacheで必要な機能をそろえることができます
面倒くさくても実行しないと、パッケージがない、とエラーが出てコンパイルが中止されるんです(´•ω•̥`)openSUSE15.1(RaspberryPi)# zypper -n install ncurses-devel perl libaio1 libaio-devel perl-Data-Dump libexpat-devel pcre pcre-devel libopenssl-develRaspberryPiOS(2020.08)# apt-get -y install libncurses5-dev perl libaio1 libaio-dev libexpat1-dev libpcre3 libpcre3-dev libssl-devAPRとそのユーティリティーライブラリをインストール
APRは/opt/apr-1.7.0に、APR-Utilは/opt/apt-util-1.6.1にライブラリをインストールします
# cd [apr-1.7.0.tar.gzが置いてあるディレクトリ] # tar xvzf apr-1.7.0.tar.gz # cd apr-1.7.0/ # ./configure --prefix=/opt/apr-1.7.0 # make # make install # cd [apr-util-1.6.1.tar.gzが置いてあるディレクトリ] # tar xvzf apr-util-1.6.1.tar.gz # cd apr-util-1.6.1/ # ./configure --prefix=/opt/apr-util-1.6.1 --with-apr=/opt/apr-1.7.0 # make # make installApache 2.4のソースコンパイルのインストール
さて、ここからが本番です。この作業は結構時間がかかりました。ラズパイだったので、40分ほどかかったかもしれないです。。
configureとmake
# cd [httpd-2.4.46.tar.gzが置いてあるディレクトリ] # tar xvzf httpd-2.4.46.tar.gz # cd httpd-2.4.46/ # ./configure --with-apr=/opt/apr-1.7.0 --with-apr-util=/opt/apr-util-1.6.1 --enable-so --enable-ssl --enable-mods-shared=all --enable-mpms-shared=allそこで、configureの指定として、APRとAPR-Utilのパスは、インストールで指定したパスを指定します。ここではAPRは「/opt/apr-1.7.0」に、APR-Utilは「/opt/apr-util-1.6.1」にインストールしていて、それ使いました。
またSSLを有効にしています。
※ もしOpenSSLのパスを変えるには「--with-ssl=/usr/local/ssl」のように、インストール先を指定するのですが、私の環境ではOpenSSLはパッケージデフォルトのものを使っているので、特に変えていません。
私は上記の必要なパッケージをすべてインストールしたところ、エラーなくconfigureできました(*´꒳`*)さて、肝心なコンパイルとインストールです。そこでエラーが出たら、ただでさえ機能てんこ盛りなApacheなので、どこでエラーが出たかを探し回ると面倒です( ˙꒳˙ᐢ )
# make # make installエラーなくコンパイルできれば、インストールは完了です♪(*˘︶˘*).。.:*♡
Apacheの環境設定
インストールできたら、さぁ次は設定ファイルです( ˙꒳˙ᐢ )
ソースコンパイルでApacheをインストールすると、Apache本体は/usr/local/apache2にインストールされます。設定ファイルは/usr/local/apache2/conf/に格納されるので、その中にApacheの環境設定を行います。[Apacheの基本設定] # vi /usr/local/apache2/conf/httpd.conf/usr/local/apache2/conf/httpd.conf… #ServerName www.example.com:80 ServerName localhost:80 ← この行を↑の直下に追記します … DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs"> … Options Indexes FollowSymLinks ↑ 先頭に「#」を付けてコメントアウトします (ページとして公開されてないディレクトリは無駄なアクセスを許可しないこと) … #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so #LoadModule ssl_module modules/mod_ssl.so ↑の2つの行を探して、いずれも「#」を消して、soライブラリを読み込みます … #Include conf/extra/httpd-ssl.conf ↑の「#」を消して、conf/extra/httpd-ssl.confを読み込めるようにします …[ApacheのSSL(https)の設定] # vi /usr/local/apache2/conf/extra/httpd-ssl.conf/usr/local/apache2/conf/extra/httpd-ssl.conf… SSLCertificateFile "/usr/local/apache2/conf/server.crt" … SSLCertificateKeyFile "/usr/local/apache2/conf/server.key" …ここでは、httpsに必要な鍵の場所は、設定ファイルと同じ/usr/local/apache2/conf/に位置することにしました。
SSL証明書作成
本来は証明書をルート認証機関を経由しての作成ですが、ここではあくまでもApacheをhttpsに対応させる手法を優先させるので、証明書の発行機関は触れません。なのでアクセスするとセキュリティの警告は出ます【。。。】
# cd /usr/local/apache2/conf/ # openssl genrsa -out server.key 2048 # openssl req -new -key server.key -out server.csrSSL鍵を作成するプロセスで、組織のプロフィールを入力する対話もありますが、以下の入力で問題なく証明書は作成できます
# openssl req -new -key server.key -out server.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:<what entry=住んでいる都道府県 example=Kanagawa> Locality Name (eg, city) [Default City]:<what entry=住んでいる市町村 example=Miura> Organization Name (eg, company) [Default Company Ltd]:<what entry=任意の組織名> Organizational Unit Name (eg, section) []:<what entry=任意の組織単位> Common Name (eg, your name or your server's hostname) []:<what entry=ドメイン名 example=kazumi-jam.chips.jp> Email Address []:<what entry=メールアドレス example=rei@example.com> Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:<what entry=とりあえず適当> An optional company name []:<what entry=とりあえず空白Enter>わかりやすく色分けしたいので、XML風に「何を入力すればいいか」を付け加えてみました(*˘︶˘*) XMLタグ風に「<what entry=…」となっているのは、何を入力すればいいのか「example=…」は入力の例です。なお実際は空白が入っていてもかまいません。
例: State or Province Name (full name) []: Kanagawa Pref. Locality Name (eg, city) [Default City]: Miura cityserver.csrを作成し終えたら、証明書一式を作成します。
# openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt「-days」オプションがないと90日間しか有効期間がないので実験目的以外では使い物になりません。なのでここでは一応10年間として「-days 3650」としています。それでも証明書自体がオレオレ証明書で信頼された機関から発行されたものではないですが…(*˘ᗜ˘*;)
さて、SSL証明書を作成したら、他の人に触れないように、パーミッションを変更します。
# chmod 600 /usr/local/apache2/conf/server.crt # chmod 600 /usr/local/apache2/conf/server.csr # chmod 600 /usr/local/apache2/conf/server.key # ls -l /usr/local/apache2/conf/ 合計 108 drwxr-xr-x 2 root root 313 6月 24 13:08 extra -rw-r--r-- 1 root root 19316 6月 24 13:07 httpd.conf -rw-r--r-- 1 root root 13064 6月 24 13:03 magic -rw-r--r-- 1 root root 60847 6月 24 13:03 mime.types drwxr-xr-x 3 root root 37 6月 24 13:03 original -rw------- 1 root root 1379 6月 24 13:06 server.crt -rw------- 1 root root 1119 6月 24 13:04 server.csr -rw------- 1 root root 1675 6月 24 13:03 server.key「ls -l」コマンドで、「server.crt」など証明書鍵関連の3ファイル(上のリストだと下3行)が、所有者rootでパーミッションが「rw-------(600)」であることを確認します。秘密鍵の中身が他のユーザーから見える時点でセキュリティ違反ですからね。。
Apacheサービスの起動
Apacheサービスの起動スクリプト作成&有効化
Apacheに必要な環境設定と鍵はそろいました。なので、起動できるようにしたいと思います。起動スクリプトはSystemdなので、/etc/systemd/systemに作成します
# cd /etc/systemd/system # vi httpd.servicehttpd.service[Unit] Description=Apache [Service] Type=forking ExecStart=/usr/local/apache2/bin/apachectl start ExecStop=/usr/local/apache2/bin/apachectl stop [Install] WantedBy=multi-user.targetここではSystemdのスクリプトは詳しく説明しませんが、Apacheの起動ファイル本体は/usr/local/apache2/binにあるので、その中のApacheサービス起動の「apachectl」をコマンド実行することで、Apacheの起動や停止ができます。また起動と実行は、Apacheの場合は、Webサーバーのプロセスはサブプロセスとして実行される(要は、ある端末で起動実行すると「実行中」の状態になって他の操作ができなくなるのではなく、コマンド入力に戻って他の操作をそのまま実行できる。わかるかな??)ので、Typeはforkingを指定します。
ファイアウォールの設定
続いて、ポート80(http)と443(httpd)を受け付けます。
なお、前提の通り、サーバーとクライアントは192.168.1.0/24のネットワークに属しているので、それ以外の外部からのアクセスは受け付けないので、以下のようにrich ruleで許可します。openSUSE15.1(RaspberryPi)(firewalld)# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="80" protocol="tcp" accept' # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="443" protocol="tcp" accept' # firewall-cmd --reloadRaspberryPiOS2020.08(ufw)# ufw allow proto tcp from 192.168.1.0/24 to any port 80 # ufw allow proto tcp from 192.168.1.0/24 to any port 443 # ufw status numbered Status: active To Action From -- ------ ---- [ 1] 30303/tcp ALLOW IN 192.168.1.0/24 [ 2] 5900:5999/tcp ALLOW IN 192.168.1.0/24 [ 3] 80/tcp ALLOW IN 192.168.1.0/24 [ 4] 443/tcp ALLOW IN 192.168.1.0/24起動と動作確認
それでは、起動します。enableでの常時起動有効化&statusで「Active」「Running」になっていることを確認。
# systemctl start httpd # systemctl enable httpd # systemctl status httpdしかし…!!
openSUSEだと、systemctl start httpdでApacheの起動が失敗しました!!(´•ω•̥`)openSUSE15.1(raspberryPi)# journalctl -xe上記コマンドで得られるジャーナルログを確認すると、Raspberry PiのopenSUSEでは、Apacheの設定ファイルで初期で指定されているユーザー「daemon」が存在しないことがわかりました。なので、Apacheのプロセスを起動するユーザーを新たに作成することにしました。。。
openSUSE15.1(raspberryPi)# useradd -m apache # passwd apache # vi /usr/local/apache2/conf/httpd.conf …(中略)… User daemon ← apacheに変更 Group daemon ← usersに変更 …(中略)… # systemctl start httpdopenSUSEでは、デフォルトではユーザーグループがユーザー名と同じで作成はなく「users」グループとして作成される。
これで「systemctl start httpd」で起動できるようになりました!!
Windowsクライアント側から、ブラウザでhttps://[LinuxサーバーのIPアドレス]/を入力して確認します。
ここではLinuxのWebサーバーは192.168.1.18なので、https://192.168.1.18にて。
もちろん証明書は信頼された機関発行ではないので、プライバシーエラーになります;;その際は「そのままアクセスする」を選んで先に進みます(ChromeやFirefoxでふるまいは違うけど。。)上の画像は仮想マシンでやった場合のキャプチャですが、Raspberry Piでも上と同じ画面が出るので、成功です!!( ˶˙ᵕ˙˶ )
次回
PHPを導入して、Webアプリサーバーの基盤を掲載します
- 投稿日:2020-09-17T12:19:31+09:00
Ubuntu20.04とRaspberry PiでIPsecゲートウェイの簡易VPN構築 - 2.StrongSwan VPN接続確認
前提と準備
Linuxサーバー構築の記事
- Sambaでファイルサーバー構築(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)
- LinuxでApache2.4+PHP7.4をソースコンパイル - 1.Apache導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 2.PHP導入 /【Raspberry Pi】
- LinuxでApache2.4+PHP7.4をソースコンパイル - 3.MySQL導入/【Raspberry Pi】
- LinuxでApache2.4+PHP7.4 - 4.セキュリティ(chownとfirewalld)
- LinuxでIPsecゲートウェイをVPN構築 - 1.StrongSwan導入 /【Ubuntu 20.04+Raspberry Pi】
- LinuxでIPsecゲートウェイをVPN構築 - 2.VPNへの接続確認 /【Ubuntu 20.04+Raspberry Pi:この記事】
前回はStrongSwanのソースコンパイルによるIPsec-VPN環境の構築を行いましたが、今回はVPNに実際に接続できるか確認しましょう!(˶ ・ᴗ・ )੭⚐⚑
環境
- IPsecプログラム:StrongSwan 5.9.0(ソースコンパイル)
- IPsec交渉受信側:Raspberry Pi 3B+ / Raspberry Pi OS(2020/08版)(armhf(v7)、32bit)
- IPsec交渉発信側:Hyper-V(第2世代)のx64仮想機 / Ubuntu 20.04(x86_64)
- VPNに接続するクライアントとサーバーを別途用意(私はここではUbuntuとCentOSのWebサーバーを用意しました)
前提
- OSは最小限のインストール。また、最新の状態でOSをアップデートしていること
- ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
- IPsecゲートウェイは、ファイアウォールはufwを使う(ラズパイのRaspberry Pi OSでは、firewalldについて、IPv6周りの連動が糞だったので、Debian系標準のufwを使用することにしました)
サーバー条件
IPアドレスとネットワーク構築図
IPsec交渉受信側ゲートウェイ(下の図の左、Raspberry Pi):
- インターネット側(eth0):192.168.1.22
- VPN領域側(eth1):192.168.2.1
IPsec交渉発信側ゲートウェイ(下の図の右、Ubuntu 20.04):
- インターネット側(eth0):192.168.1.18
- VPN領域側(eth1):192.168.5.1
ネットワークセグメント:
- インターネット接続可能:192.168.1.0/24
- Raspberry Pi(図の左の交渉受信側)セキュアセグメント:192.168.2.0/24
- Ubuntu 20.04(図の右の「CentOS 8」と記載されている交渉発信側)セキュアセグメント:192.168.5.0/24
VPNに接続する端末:
- クライアント(Ubuntu 20.04):192.168.2.2(192.168.2.0/24に属する)
- Linux Webサーバー(CentOS 8.1):192.168.5.2(192.168.5.0/24に属する)
IPsec領域関連:
ここでは、192.168.2.2のUbuntuクライアントが、192.168.5.2のLinux WebサーバーにVPN接続できるかを試します。なおVPNに接続しているサーバーとクライアントともに、VPNの範囲のみ接続して、インターネットには接続しないこととします。
パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年9月時点)
- zlib-1.2.11.tar.gz
- strongswan-5.9.0.tar.gz
それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。
ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。
作業手順
VPNにサーバーとクライアントを接続する
VPN領域内のIPアドレス割り振り
前回ではeth1はあくまでもネットワークアダプタを追加しただけであって、まだIPアドレスは割り振られていません。ラズパイの場合(Raspberry Pi OS)は/etc/dhcpcd.confを手動で追加するしかなかったんです。。もちろんdhcpcd.confにはデフォルトゲートウェイもDNSサーバーも指定があるので、複数指定するとネットワークの順位が混乱するので、新設したeth1には、IPアドレスのみを記載。
参照記事:
RaspberryPiOS(2020.08)# vi /etc/dhcpcd.conf/etc/dhcpcd.conf(RaspberryPiOS)[以下のインターフェースの情報を最終行に追記] #interface eth1 interface eth1 static ip_address=192.168.2.1/24 noipv6RaspberryPiOS(2020.08)# reboot # ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether [最初からあるネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff inet 192.168.1.22/24 brd 192.168.1.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet6 [最初からあるネットワークアダプタのIPv6アドレス] scope global dynamic noprefixroute valid_lft 14373sec preferred_lft 12573sec 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether [増設ネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff inet 192.168.2.1/24 brd 192.168.5.255 scope global noprefixroute eth1 valid_lft forever preferred_lft forever inet6 [増設ネットワークアダプタのIPv6アドレス] scope link noprefixroute valid_lft forever preferred_lft forever # ip route default via 192.168.1.1 dev eth0 proto static metric 100 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.22 metric 100 192.168.2.0/24 dev eth1 proto kernel scope link src 192.168.2.1 metric 101IPアドレスの設定ファイルってディストリビューション依存しすぎていて、慣れないと大変です٩(.› ‹.♡)۶
eth1にIPアドレスを設定しました。もちろんルーティングにも192.168.2.0/24も認識されました。その一方で、Hyper-VのUbuntuだとSSHではなくGUI画面で設定できるから、そこにアドレスとネットマスクだけを指定して設定を保存するだけでOKです٩(.› ‹.♡)۶
Ubuntu20.04(Hyper-V/x64)# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether [最初からあるネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff inet 192.168.1.18/24 brd 192.168.1.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet6 [最初からあるネットワークアダプタのIPv6アドレス] scope global temporary dynamic valid_lft 14043sec preferred_lft 12243sec 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether [増設ネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff inet 192.168.5.1/24 brd 192.168.5.255 scope global noprefixroute eth1 valid_lft forever preferred_lft forever inet6 [増設ネットワークアダプタのIPv6アドレス] scope link noprefixroute valid_lft forever preferred_lft forever # ip route default via 192.168.1.1 dev eth0 proto static metric 100 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.18 metric 100 192.168.5.0/24 dev eth1 proto kernel scope link src 192.168.5.1 metric 101VPN領域内のネットワークにサーバーとクライアントをLANケーブル接続する
これは言うまでもないですね。サーバーとクライアントをLANケーブルでつないで、IPアドレスを手動で設定します(DHCPサーバーがVPN領域内にないので、手動設定するしかないです)
「サーバー条件」を参照しての通り、下の図のようなLANケーブル接続でIPアドレスを割り振っていきます。もちろん仮想マシンの場合は仮想スイッチを割り当てるだけでOKです。
- Ubuntuクライアントをラズパイに接続(192.168.2.0/24)。IPアドレスを192.168.2.2に設定
- Linux WebサーバーをHyper-V仮想機に接続(192.168.5.0/24)。IPアドレスを192.168.5.2に設定 ※ 図の左上の「openSUSE」はRaspberry Pi OSに、右上の「Linuxルーター CentOS 8」はUbuntu 20.04に読み替えてください。
VPNのネットワーク接続動作確認
Pingはこの時点で通っている
画面上はCentOS+openSUSEのものですが、今回のUbuntuを使うケースでも、クライアント(192.168.2.2)から対向のVPN領域にあるWebサーバー(192.168.5.2)に通るか確認したら、あっさり通っていました( ´థ౪థ)やはりUbuntuのIPsecゲートウェイのケースでも、Webがその時点でVPN領域越しに見られるというわけじゃないみたいです。
もちろんwgetでも「No route」となってしまうはずですufwの転送許可
IPsecでトンネリングしたパケットも、IPsecゲートウェイのufwでまた転送許可のルールを追加しなければならないので、VPNにあるサーバーとクライアントが通信するポートを開放した。ここでは、クライアントが192.168.2.2、サーバーが192.168.5.2なので、192.168.2.0/24 → 192.168.5.0/24宛ての転送許可をルールに加えるが、ufwの場合はrouteを指定する必要がある。
Webサーバーが使うポートは、Webである80・443・8080・8443なので、当然以下のコマンドを入力すればVPN越しにIPsecゲートウェイが転送してくれるはず。
[192.168.2.0/24 → 192.168.5.0/24 HTTP 許可] # ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 80 proto tcp [192.168.2.0/24 → 192.168.5.0/24 HTTPS 許可] # ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 443 proto tcp [192.168.2.0/24 → 192.168.5.0/24 ポート8080 許可] # ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 8080 proto tcp [192.168.2.0/24 → 192.168.5.0/24 ポート8443 許可] # ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 8443 proto tcp [確認するには] # ufw status numbered Status: active To Action From -- ------ ---- [ 1] 30303/tcp ALLOW IN 192.168.1.0/24 …(中略)… [10] 192.168.5.0/24 80/tcp ALLOW FWD 192.168.2.0/24 [11] 192.168.5.0/24 443/tcp ALLOW FWD 192.168.2.0/24 [12] 192.168.5.0/24 8080/tcp ALLOW FWD 192.168.2.0/24 [13] 192.168.5.0/24 8443/tcp ALLOW FWD 192.168.2.0/24 …(中略)…参照:
Hyper-V仮想マシンのCentOS 8.1ではfirewalldとdirectの相性が悪い(具体的には、たぶんnftablesとの登録がうまくいっていないみたい)ために、転送ルールをfirewalldに登録してもうまく転送できない問題が発生していたが、Ubuntu20.04とRaspberry Pi OS(2020/08版)のufwではまだそういう問題が発生していなく、今後Debian系のOSはnftablesを推奨するので、早期にnftablesと転送ルールの問題が解決しなければ、CentOSの二の舞になるかもしれませんが…
nftables関連でいろいろ参考させていただきました!( ´ •̥ ̫ •̥ ` )- ̗̀ ♡ ̖́-
- centOS8でDockerコンテナから名前解決ができない話をnftコマンドで解決する
- netfilterとfirewalldとiptablesとnftablesの関係
- Linuxにおける新たなパケットフィルタリングツール「nftables」入門 - さくらのナレッジ
Webサーバーにアクセスできるか確認
IPsecゲートウェイの両方で転送を許可できたら、VPN越しにクライアントからVPN内のサーバーにアクセスできるかやってみました。
この成功画面では、CentOS+openSUSEの場合での画面ですが、実際Ubuntuでもうまくいっています!!
セキュリティ確認
IPsecゲートウェイをまたぐパケットは暗号化されている??
やはり、Ubuntuの場合でも、下の画面みたいにパケットがIPsecトンネルでは暗号化を確認しています(˶ ・ᴗ・ )੭♡♡
わかりやすくHTTP(ポート80)で「QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ…」をHTTPSで暗号化させずにクライアントでサーバーからページをアクセスしてみたけど、IPsecゲートウェイ間のトンネリングでそれを拾ってみてみると、暗号化されていました!!
まとめ
StrongSwanでRaspberry Pi OSとHyper-V仮想マシンのUbuntu 20.04でも、IPsecゲートウェイの構築を行い、IPsec-VPNとしての用途を満たすことは確認した。やはりセキュリティ対策についてもCentOSの場合ともやはり変わらないことはわかったが…今後はnftablesのufwやfirewalldとの相性の課題もまだあるみたいだし…⸝⸝ᵕ ᵕ⸝⸝
- 投稿日:2020-09-17T09:59:57+09:00
Javaでcronのプログラムを作ろう!!(TaskScheduler)
Java(cron4j)
・cronとは、多くのUNIX系OSで標準的に利用される常駐プログラム(デーモン)の一種で、利用者の設定したスケジュールに従って指定されたプログラムを定期的に起動してくれるもの。(*IT用語辞典参照)
jar
下記リンクからjarファイルをダウンロードしてIDEに設定しよう!!
https://www.sauronsoftware.it/projects/cron4j/download.phpTaskクラス
まず、実行したい処理を書くクラスを作ろう!!
CronTaskimport java.util.Date; public class CronTask implements Runnable{ @Override public void run() { System.out.println(new Date()+": Hiiiii! cron4j!"); } }Schedulerクラス
MyCronAppTestimport it.sauronsoftware.cron4j.Scheduler; public class MyCronAppTest { public static void main(String[] args) { MyCronAppTest app = new MyCronAppTest(); try { app.schedulerSimple(); System.out.println("Press Ctrl+C to stop."); Thread.sleep(100000000); } catch (InterruptedException e) { e.printStackTrace(); } } public void schedulerSimple() { Scheduler scheduler = new Scheduler(); // every minute. scheduler.schedule("* * * * *", new CronTask()); // start cron4j scheduler. scheduler.start(); } }おまけ(Servletを使ったScheduler)
HelloServletimport java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import it.sauronsoftware.cron4j.Scheduler; public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void schedulerSimple() { Scheduler scheduler = new Scheduler(); // every minute. scheduler.schedule("* * * * *", new CronTask()); // start cron4j scheduler. scheduler.start(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { MyCronApp app = new MyCronApp(); try { app.schedulerSimple(); System.out.println("Press Ctrl+C to stop."); Thread.sleep(100000000); } catch (InterruptedException e) { e.printStackTrace(); } response.getWriter().append("Hello Servlet"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
- 投稿日:2020-09-17T09:59:57+09:00
Javaでcronのプログラムを作ろう!!(タスクスケジューラー)
Java(cron4j)
・cronとは、多くのUNIX系OSで標準的に利用される常駐プログラム(デーモン)の一種で、利用者の設定したスケジュールに従って指定されたプログラムを定期的に起動してくれるもの。(*IT用語辞典参照)
jar
下記リンクからjarファイルをダウンロードしてIDEに設定しよう!!
https://www.sauronsoftware.it/projects/cron4j/download.phpTaskクラス
まず、実行したい処理を書くクラスを作ろう!!
CronTaskimport java.util.Date; public class CronTask implements Runnable{ @Override public void run() { System.out.println(new Date()+": Hiiiii! cron4j!"); } }Schedulerクラス
MyCronAppTestimport it.sauronsoftware.cron4j.Scheduler; public class MyCronAppTest { public static void main(String[] args) { MyCronAppTest app = new MyCronAppTest(); try { app.schedulerSimple(); System.out.println("Press Ctrl+C to stop."); Thread.sleep(100000000); } catch (InterruptedException e) { e.printStackTrace(); } } public void schedulerSimple() { Scheduler scheduler = new Scheduler(); // every minute. scheduler.schedule("* * * * *", new CronTask()); // start cron4j scheduler. scheduler.start(); } }おまけ(Servletを使ったScheduler)
HelloServletimport java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import it.sauronsoftware.cron4j.Scheduler; public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void schedulerSimple() { Scheduler scheduler = new Scheduler(); // every minute. scheduler.schedule("* * * * *", new CronTask()); // start cron4j scheduler. scheduler.start(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { MyCronApp app = new MyCronApp(); try { app.schedulerSimple(); System.out.println("Press Ctrl+C to stop."); Thread.sleep(100000000); } catch (InterruptedException e) { e.printStackTrace(); } response.getWriter().append("Hello Servlet"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
- 投稿日:2020-09-17T02:48:04+09:00
IPエイリアスに対して、ssh でポートフォワード出来るって知ってました?
聞いてみると、けっこう知らない人が多かったので、書いときます。
タイトルに書いたとおり、IPエイリアスに対して ssh でポートフォワードが出来ます!
これだけだと、ちょっと意味わかりにくいですよね。
つまり、複数の宛先に対して、同一ポート番号での フォワード処理が出来るってことです。例えば、サーバAの 443番(https)に向けた通信と サーバBの 443番(https)に向けた通信を、物理NIC を追加することなく、また、ローカルの監視ポート番号を変えることなく、1台のサーバで、単一コマンドにてフォワード出来るんです。
もちろん、443番に限らず、どんなポート番号でも同じです。例
# ifconfig eth0 aaa.aaa.aaa.aaa ...と 物理NICに設定されていたとして、
# ifconfig eth0:0 xxx.xxx.xxx.xxx # ifconfig eth0:1 yyy.yyy.yyy.yyy # ifconfig eth0:2 zzz.zzz.zzz.zzzと、IPエイリアスを追加設定したとします。
ここで、特権ポートなんで root で、
# ssh -L aaa.aaa.aaa.aaa:443:localhost:1443 -L xxx.xxx.xxx.xxx:443:localhost:2443 -L yyy.yyy.yyy.yyy:443:localhost:3443 -L zzz.zzz.zzz.zzz:443:localhost:4443 user@serverと 出来るということです。
当然 このあと、多段転送で 目的のサーバにフォワードさせていくわけですが、
上の転送が出来るメリット
は、通信ポートが変えられないアプリケーションを使っていた場合に、威力を発揮します。
特に、Windowsアプリは ポートを変えられないケースが多いですね。
そんな場合にも、aaa.aaa.aaa.aaa の 443番と、xxx.xxx.xxx.xxx の 443番 等を、同時に 使えるんです!さらに、Windows 上にて!
コントロールパネルの ネットワーク設定で、
物理NIC に 複数のIPアドレスを付与
できますよね?
ここで、Cygwin の ssh でも 同様の処理が出来ます。例えば これと併用すると...
OpenBlocks を使い、遠隔地のインターネット公開されていない内部ドメインのWebサーバを、SSL-VPN装置を使わずに 安全に利用するには(OpenBlocks を、簡易VPN機器っぽく使う)
遠隔地から 内部ネットワークの複数サーバに向けて、さらに VPN っぽく遠隔利用できるわけです。便利な世の中になったもんです。(って、昔から です)