20200624のLinuxに関する記事は12件です。

ハードリンクとシンボリックリンクの違いについて挙動を調べてみた

ハードリンクとシンボリックリンクの違いを知りたくて調べてみました。

環境はこちらです。

# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

ハードリンクとは?

ハードリンクとは、ファイルシステムの機能の一つで、あるファイルやディレクトリの実体に複数の名前を付け、それぞれが実際のファイル名/ディレクトリ名として等しく機能するようにしたもの。ハードリンクを作成すると同じファイルを持つこととなる。
ファイルの実体に名前を付けた時の ( どこかのディレクトリにファイル名を登録する )、ファイルの実体とファイル名の対応自体がハードリンクで、複数つけることもできる。

シンボリックリンクとの違いは、シンボリックリンクは指定したファイルに繋がるパスを持ったファイルが作成されるが、ハードリンクは指定したファイルそのものと同じデータを持つ事になる。

シンボリックリンクとは?

指定したファイルのパスを持つファイルが作成される。そのため、ファイルとしては新たに作成される。

ハードリンクを作成してみた

ファイルをファイル名付きで作成した時点でハードリンクは作成される。なので、vi 新しいファイル名echo "hoge" > 新しいファイル名などをしてファイルを作成した時点でハードリンクが一つ自動で作成される。
ここでは、作成したファイル(ハードリンク一つのファイル実体)に対して追加でハードリンクを作成してみる。
lnコマンドを使ってハードリンクを作成することができる。
ln 元のファイル ハードリンクの名前
ハードリンクを作成した場合、元のファイルとハードリンクのinode番号(一番左の番号)が同じであることがわかる。
ここでは、8409199のこと。
inode番号はファイルの実態であるため、見かけはファイルが二つあるように見えるが、実態としては一つのファイルであると言える。

# echo "hogehoge2" > test
# ln test hardlink
# ls -li
8409199 -rw-r--r--  2 root root   10  6月 24 21:13 hardlink
8409199 -rw-r--r--  2 root root   10  6月 24 21:13 test

シンボリックリンクを作成してみた

続いてシンボリックリンクを作成してみる。
ln -sでシンボリックリンクを作成できる。
下の結果から、inode番号が異なるファイルが作成されたことがわかる。これは、指定したファイルを参照するためのファイルが作成されたとみることができる。

# ls -il test symblink hardlink 
8409199 -rw-r--r-- 2 root root 10  6月 24 21:13 hardlink
8409209 lrwxrwxrwx 1 root root  5  6月 24 21:53 symblink -> test
8409199 -rw-r--r-- 2 root root 10  6月 24 21:13 test

ちなみに各ファイルの中身をみてみると全て同じであることがわかる。
全て同じファイルを参照しているため!

# cat test
hogehoge2
# cat hardlink 
hogehoge2
# cat symblink
hogehoge2

シンボリックリンクのファイル内を変更しても、全てのファイルが変更される。
全て同じファイルを参照しているため!!

# echo "add hoge" >> symblink
# cat test
hogehoge2
add hoge
# cat hardlink 
hogehoge2
add hoge
# cat symblink
hogehoge2
add hoge

異なるファイルシステムにハードリンク・シンボリックリンクを作成してみた!

ハードリンクはファイルシステム内で一意のinode番号が割り振られており、異なるファイルシステムにハードリンクを作成することはできない。その挙動をみてみる。

まずファイルを作成してみる。

# touch fileA
# ls -i fileA 
8409208 fileA

dfコマンドでファイルシステムを確認。ホームディレクトリで作業していたため、fileAのあるファイルシステムはマウント位置が/のところとなっている。今回は/dev/shm以下にハードリンクを作成した時の挙動をみてみる。

# df
ファイルシス            1K-ブロック    使用  使用可 使用% マウント位置
devtmpfs                     495352       0  495352    0% /dev
tmpfs                        507412       0  507412    0% /dev/shm
tmpfs                        507412    6876  500536    2% /run
tmpfs                        507412       0  507412    0% /sys/fs/cgroup
/dev/mapper/centos-root     6486016 1198776 5287240   19% /
/dev/sda1                   1038336  139372  898964   14% /boot
tmpfs                        101484       0  101484    0% /run/user/0

ハードリンクを作成するとエラーが発生する。これにより異なるファイルシステムにハードリンクを作成することができないことがわかった。
シンボリックリンクの場合は異なるファイルシステムでもリンクを作成することができる。
しかし、リンク切れが発生してしまう。

# ln fileA /dev/shm/fileA-2
ln: `/dev/shm/fileA-2' から `fileA' へのハードリンクの作成に失敗しました: 無効なクロスデバイスリンクです
# ln -s fileA /dev/shm/fileA-2
# cat /dev/shm/fileA-2
cat: /dev/shm/fileA-2: シンボリックリンクの階層が多すぎます
# file /dev/shm/fileA-2
/dev/shm/fileA-2: broken symbolic link to `fileA'

続いて作成したハードリンクを異なるファイルシステムに移動させてみる

fileAのハードリンクを三つ作成し、そのうちの一つを異なるファイルシステムに移動させてみる。

# ln fileA fileA-2
# ln fileA-2 fileA-3
# ls -li fileA*
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA-2
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA-3

このうち、file-3を/dev/shm配下に移動してみる。
ls -lの結果から移動後にハードリンク数が減っていることがわかる。
移動まえ)
8409208 -rw-r--r-- 3 root root 0 6月 24 21:35 fileA-2
         ↑ここが3となっており、ハードリンクが三つあると表記されている。
移動後)
8409208 -rw-r--r-- 2 root root 0 6月 24 21:35 fileA-2
file-1とfile-2はハード数が2になっている。
18911 -rw-r--r-- 1 root root 0 6月 24 21:35 /dev/shm/fileA-3
file-3に関しては1つになっている。

# mv fileA-3 /dev/shm/
# ls -li fileA*
8409208 -rw-r--r-- 2 root root 0  6月 24 21:35 fileA
8409208 -rw-r--r-- 2 root root 0  6月 24 21:35 fileA-2
# ls -li /dev/shm/fileA-3 
18911 -rw-r--r-- 1 root root 0  6月 24 21:35 /dev/shm/fileA-3

ファイルの中身を編集してみると、異なるファイルシステムに移動したファイル(fileA-3)には変更が反映されていない。

# echo "hello" > fileA
# cat fileA
hello
# cat fileA-2 
hello
# cat /dev/shm/fileA-3 
((何も表示されない!!))

このことから、mvコマンドによりハードリンクを移動させると、元のファイルシステムからは削除され、指定したファイルシステム内にファイルが新しく作成される挙動になっていることがわかった。

終わりに

今回は、ハードリンクとシンボリックリンクについて調べて、挙動を確認してみました。
基本的なことはまだまだわからないことも多いですが、一つずつ勉強していこうと思います。

参考)
https://qiita.com/lnznt/items/6178e1c5f066f22fe9c2#%E7%95%B0%E3%81%AA%E3%82%8B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%B8%E3%81%AE-mv

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Live...Everton vs Norwich City Live Stream

Norwich City vs Everton: TV Channel, Live Stream, EPL Today Football Match.  Everton travels to Norwich City for both teams' second match back after the resumption of the Premier League season.

Norwich City vs Everton.jpg

Norwich suffered a 3-0 loss against Southampton over the weekend, while Everton drew 0-0 at home to Liverpool.

Both sides will be hoping they can make a return the scoresheet this time around, with Norwich aiming to reduce the six-point gap between themselves and safety and Everton aiming for a top-half finish.

When is it and what time is kick-off?
The match will begin at 6 pm on Wednesday, 24 June at Carrow Road.

How can I watch it live stream and on TV?

Who: Norwich City vs. Everton
When: Wednesday at 1 pm ET
Where: Carrow Road
TV: NBCSportsGold.com PL Pass
Online streaming: Catch select Premier League matches on fuboTV (Try for free. Regional restrictions may apply.)
Follow: CBS Sports App

The match will be broadcast live on BBC Two (first half), BBC One (second half), and the BBC iPlayer.

What is the team news?
Norwich will have Marco Stiepermann available again after having tested positive for Covid-19 earlier in the month. There were no injuries for Norwich in their last game so it should be a near-full squad for Farke.

Everton is still without Yerry Mina, Fabian Delph, and Theo Walcott, while Morgan Schneiderlin has been sold to Nice. Djibril Sidibe is unlikely to be fit in time for this game.

Predicted line-ups
Norwich: Krul; Aarons, Godfrey, Klose, Lewis; McLean, Tettey; Buendia, Cantwell, Duda; Pukki.

Everton: Pickford; Coleman, Holgate, Keane, Digne; Iwobi, Davies, Gomes, Bernard; Calvert-Lewin, Richarlison.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxでApache2.4(httpd 2.4.43)+PHP7.4をソースコンパイルしてWebサーバー構築 - 3.MySQL8.0導入編

前提と準備

Linuxサーバー構築の記事

前回はApache2.4にPHP7.4をソースコンパイルでWebアプリ環境を構築しましたが、今回は、前回に引き続き、データベースサーバーを構築します(⑅•ᴗ•⑅)

データベースサーバーはWebサーバー本体と切り離し可能ですが、今回は簡単なため、Webサーバーと一体でデータベースのMySQLを構築します

環境

  • Webサーバープログラム:Apache 2.4.43 + PHP 7.4.6 + MySQL 8.0
  • クライアント:Windows10 Pro
  • サーバーのアーキテクチャ:x64(動作はHyper-Vの第2世代で確認) Linuxのディストリビューション:CentOS 8.1 / openSUSE 15.1 Leap / Ubuntu 20.04(すべて64bit)

前提

  • ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
  • どのディストリビューションでも、ファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)
  • 前回の記事のApache+PHP導入を完了していること

サーバー条件

IPアドレス

  • クライアント:192.168.1.11
  • Webサーバー:192.168.1.18(どのディストリビューションでも同じIPアドレスで検証)
  • データベースサーバー:(Webサーバーと一体)
  • 所属ネットワークセグメント:192.168.1.0/24 Webサーバー.png

パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)

  • zlib-1.2.11.tar.gz
  • apr-1.7.0.tar.gz
  • apr-util-1.6.1.tar.gz
  • mysql80-community-release-el8-1.noarch.rpm (CentOS 8.1)
  • mysql80-community-release-sl15-3.noarch.rpm (openSUSE 15.1)
  • mysql-apt-config_0.8.15-1_all.deb (Ubuntu 20.04)
  • oniguruma-devel-6.8.2-1.el8.x86_64.rpm (CentOS 8.1)
  • httpd-2.4.43.tar.gz
  • php-7.4.6.tar.gz

それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。

ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。

作業手順

MySQL 8.0の導入

MySQLのインストール

ディストリビューションの標準パッケージコマンドにあるMySQLは、バージョンが古いものや互換であるMariaDBであることが多いため、明示的なMySQLのバージョンを導入する場合は、MySQL公式からレポジトリをダウンロードする必要があります。

ダウンロードしたレポジトリを適用し、MySQLをインストールします。

CentOS8.1
# cd [mysql80-community-release-el8-1.noarch.rpmの配置されているディレクトリ]
# dnf -y install mysql80-community-release-el8-1.noarch.rpm
# dnf -y install mysql-server
openSUSE15.1
# cd [mysql80-community-release-sl15-3.noarch.rpmの配置されているディレクトリ]
# zypper install mysql80-community-release-sl15-3.noarch.rpm
…(中略)…
mysql80-community-release-sl15-3.noarch (RPM ファイルキャッシュ): 署名の検証に失敗しました [4-署名の公開鍵がありません]
中止(A)、再試行(R)、無視(I)? [a/r/i] (a):  ← 「i」で続行する

# zypper install mysql-community-server
鍵を拒否しますか(R)? 今後ずっと信頼しますか(A)? [r/a/?] (r):  ← 「a」で続行する
(あとはインストールするか問われるので「y」を選択)
Ubuntu20.04
# cd [mysql-apt-config_0.8.15-1_all.deb.debの配置されているディレクトリ]
# dpkg -i mysql-apt-config_0.8.15-1_all.deb

Which MySQL product do you wish to configure?
→「MySQL Server & Cluster」を選択

Which server version do you wish to receive?
→「mysql-8.0」を選択

Which MySQL product do you wish to configure? に戻る
→「Ok」を選択

# apt-get -y update  ← アップデート後は再起動することが望ましい

# apt-get -y install mysql-client mysql-server
→ 途中MySQLのroot(Linuxのrootではない)のパスワードを設定する必要がある

なお、MySQL 8.0の場合認証基盤がハッシュ値対応で、しかもデフォルトでハッシュ値ベースの認証基盤を有効化している場合があります。しかし、これはPHP7でも対応していないらしく(7.4になった今でも対応している話は聞いていない)、PHPで平文パスワードで記載してアクセスすると認証がうまくできない。そのため、/etc/my.cnfを修正する必要がある(CentOS8.1の場合は/etc/my.cnfでインクルードしている/etc/my.cnf.d/mysql-default-authentication-plugin.cnfを編集する)。

またUbuntu 20.04では、MySQLのapt-getでのインストール中に、MySQLのroot(Linuxのrootではない)パスワードの設定と「Select default authentication plugin」というように認証基盤の選択ができるのでありがたい(✿´ ꒳ ` )

openSUSE15.1
# vi /etc/my.cnf
CentOS8.1
# vi /etc/my.cnf.d/mysql-default-authentication-plugin.cnf
my.cnfまたはmysql-default-authentication-plugin.cnf
default-authentication-plugin = mysql_native_password ← 先頭の「#」ははずす
Ubuntu20.04の場合
[認証基盤を/etc/my.cnfの修正で行う必要はない。インストール時に選択する]
インストール中に「Select default authentication plugin」と問われる
→「Use Legacy Authentication Method」を選択する

MySQLの起動

CentOS8.1
# systemctl start mysqld
# systemctl enable mysqld
# systemctl status mysqld
openSUSE15.1・Ubuntu20.04
# systemctl start mysql
# systemctl enable mysql
# systemctl status mysql

次に、MySQLの起動を行った後に、MySQLの初期パスワードを確認するため、MySQLのログを確認。なおUbuntu 20.04ではパスワード設定をあらかじめインストール時に実施したので、初期パスワードをログから確認する作業は不要。

CentOS8.1
# less -r /var/log/mysqld.log
openSUSE15.1
# less -r /var/log/mysql/mysqld.log

その際、「[Note] A temporary password is generated for root@localhost:~」が存在すれば、初期パスワードが設定されている。なければ設定されていない(CentOS 8.1のMySQL 8.0は設定されていない)。このパスワードを用いて、MySQLコマンドラインを実行する

Ubuntu20.04はこの手順は飛ばす
[MySQL初期パスワードなし]
# mysql -u root
[MySQL初期パスワードあり]
# mysql -u root -p  ← 初期パスワードを入力してログイン

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '<MySQLのrootパスワード(Linuxのrootパスワードではない)>';
Query OK, 0 rows affected (0.00 sec)

mysql> exit

ここで、MySQLの実際に運用想定のパスワードを設定する。そこで、rootというのはLinuxのrootではなく、MySQLの中のrootであることに注意したい。

「Query OK, 0 rows affected (0.00 sec)」と出力されれば、MySQLのrootパスワードの設定が完了するので、exitで終了する。

では、設定後のMySQLのrootパスワードでログインを試す

# mysql -u root -p
Enter password:  ← MySQLのrootパスワードを入力

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.17 Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

こうなればMySQLのrootログインが成功となる。または、以下でも確認できた

# mysqladmin ping -u root -p
Enter Password:  ← MySQLのrootパスワードを入力
mysqld is alive

「mysqld is alive」となればOK

MySQLを試す

ユーザーとデータベースを作ってみる

MySQLが動いたということなので、実際ユーザーとデータベースを作ってみます。

  • データベース名:manutest
  • テストユーザー名:test
  • テストユーザーパスワード:test0
  • 文字コード:UTF-8

最初にMySQLのrootでログインします。

# mysql -u root -p
Enter password:  ← MySQLのrootパスワードを入力

mysql> CREATE DATABASE manutest CHARACTER SET utf8;
↑ データベース「manutest」を文字コードUTF-8で作成する

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| manutest           |  ← 作成したデータベースが表示される
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> CREATE USER 'test'@'localhost' IDENTIFIED BY 'test0';
↑ ユーザー名「test」をパスワード「test0」にて作成する

mysql> GRANT ALL ON manutest.* TO 'test'@'localhost';
↑ データベース「manutest」に対して、ユーザー「test」が全機能を使えるようにする

エラーがなく「Query OK, 0 rows affected」が表示されれば、データベースとユーザーは作成完了。

パスワードポリシーエラーが発生する場合

もしパスワードポリシーに反しているとエラーが発生してしまう場合は、ポリシーの状態を確認して、変更できるみたいです。ちなみにCentOS 8.1では存在せず、openSUSE 15.1では存在していました。

mysql> SHOW VARIABLES LIKE 'validate_password%';
↑ Empty setならポリシーは存在しないが、もし存在する場合は、初期では
 validate_password_lengthが8、validate_password.policyが「MEDIUM」

mysql> SET GLOBAL validate_password.length=4;
mysql> SET GLOBAL validate_password.policy=LOW;
↑ これで4文字以内のパスワード、試験目的で簡単なパスワードを設定できる

mysql> SET GLOBAL validate_password.length=8;
mysql> SET GLOBAL validate_password.policy=MEDIUM;
↑ 戻す場合

では、作成したテスト用のユーザーとデータベースで、MySQLを使えるか試します。

mysql> exit
Bye

# mysql -u test -p
Enter password:  ← パスワード「test0」を入れる
(中略)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| manutest           |  ← 作成したデータベースが表示されれば成功
+--------------------+
2 rows in set (0.00 sec)

テーブルを作成してデータを入れてみる

では、作成したデータベースに、テーブルを作ってそこにデータを入れてみます!

今回は、このテーブルをテスト用に作成します。
テーブル名:testtb

id name memo
INT VARCHAR(64) VARCHAR(256)
必須属性 PRIMARY KEY NOT NULL 初期値NULL
その他属性 AUTO_INCREMENT - -
mysql> USE manutest;
mysql> CREATE TABLE testtb (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64) NOT NULL, memo VARCHAR(256) DEFAULT NULL);
Query OK, 0 rows affected (0.11 sec)

mysql> SHOW TABLES;
+--------------------+
| Tables_in_manutest |
+--------------------+
| testtb             |
+--------------------+
1 row in set (0.00 sec)

テーブルの作成に成功したら、実際にデータを入れてみます。
テストテーブルtesttbは、idが自動採番で、nameが必須入力となるため、例として以下の値を挿入します。

  • id:(自動採番のため省略)
  • name:テスト
  • memo:Only for test.
mysql> INSERT INTO testtb (name, memo) VALUES ('テスト', 'Only for test.');
mysql> SELECT * FROM testtb;
+----+-----------+----------------+
| id | name      | memo           |
+----+-----------+----------------+
|  1 | テスト    | Only for test. |
+----+-----------+----------------+
1 row in set (0.00 sec)

このように登録したデータが文字化けすることなくデータベースに登録されました♪
成功です!

PHP上でMySQLを扱ってみる

MySQLのインストールも、動作も問題なく確認できたので、いよいよPHPからMySQLを扱ってみたいと思います。

MySQLは終了して、PHPページを作成します。

PHPからMySQLの接続を確認

まずはPHPでPOSTにて受け取ったデータをMySQLデータベースへ登録する受信PHPを作成します!っとその前に、PHPでMySQLに接続できるかちゃんと確かめないといけません(*˘ᗜ˘*;)

接続確認ページを作ります

# cd ~
# vi connect.php
connect.php
<?php
    $dsn = 'mysql:dbname=manutest; host=127.0.0.1';
    $usr = 'test';
    $pass = 'test0';

    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 と入力して確認。今回はLinuxサーバーのIPアドレスは192.168.1.18なので、ブラウザでhttps:~の後に、192.168.1.18/connect.phpをURLを入力してアクセス。

conn.png
connect.phpでは接続成功すると上記のメッセージを出力するので、↑の画像は接続が成功したんです!!

PHPからMySQLにデータを登録できるかを確認

続いて、いよいよデータが登録できるかを確認します。
再びWebページを作ります。

まずは登録フォームから。

# vi test_form.html
test_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.php
test_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=127.0.0.1';
        $usr = 'test';
        $pass = 'test0';

        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にアクセスしてみます。

reg1.png
適当に左右のフォームに文字列を入れて…(なるべく日本語で)、Submitを押します

reg2.png
成功しました!入力されたデータがPHPにPOSTされて、MySQLのデータベースに登録されました。ではコマンドラインからも確認してみましょう。

PHPでは、manutestというデータベースに、ユーザーtestで接続しているので、コマンドからもtestでMySQLにログインします。

# mysql -u test -p
Enter password:  ← パスワード「test0」を入力

mysql> USE manutest;
mysql> SELECT * FROM testtb;
+----+-----------------+----------------+
| id | name            | memo           |
+----+-----------------+----------------+
|  1 | テスト          | Only for test. |
|  2 | パンケーキ      | 食べたい       |
+----+-----------------+----------------+
2 rows in set (0.00 sec)

ちゃんと追加されていました!!(*˘ᗜ˘*).。.:*♡

あとがき

ApacheとPHP+MySQLは、私の過去の実務経験からも、大企業までも頻繁にこのパターンで使われていました。逆にJavaは少なかったかな…と感じています。

PHPのほうがJavaの商用ライセンスよりも安価でオープンなので、大企業でも、もちろん中小個人でも導入しやすいのかな…って感じがします。

LinuxへのApache+PHP+MySQLに導入する費用としては、ライセンスがいらないので、あとは給料に対する労力の費用と、中古PCやラズパイ関係なく、装置の費用なのかな…と感じがします。

導入費用が1時間2500円であれば、Webサーバーとファイルサーバーを新規構築するのに2時間かければ、合計5000円。それに、中古PC or ラズパイとHDDやSSDの新品の組み合わせが3~40000円となれば、新規導入費用は5万円弱なので、高価なWindows Serverマシンを30万円かけて買うよりは、6分の1以下と、中小企業や個人経営程度でもITソリューションの潤いはやってくるのかな…と感じる。

特に、ラズパイなどIoTの場合は、センサーなどの物性分野とハイブリッドで組み合わせて、データ化できるのも期待されるので、今後はいろいろと視野を広げて、Qiitaに載せてみたいと思う( ˙꒳​˙ᐢ )

今後と次回

PHPによるWebアプリサーバー構築のほかにも、Java(OpenJDK)によるWebアプリサーバーについても、構築に触れてみたい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

linuxでhost.docker.internalを使う (要docker-compose)

TL;DR

docker-compose.override.yaml に以下を記載

docker-compose.override.yaml
version: "3.5" # docker-compose.yamlのバージョンと合わせる

services:
  app: # host.docker.internalを使用したいサービス名
    extra_hosts:
      - "host.docker.internal:172.101.0.1" # 下のsubnetの指定に合わせる

networks:
  default:
    driver: bridge
    ipam:
      config:
        - subnet: 172.101.0.0/16 # 他のnetworkと被らないように指定

firewall設定

firewallが動いている場合は、上記subnetからのアクセスを許可する必要があるかもしれません。
firewalldのコマンド例を記載しておきます。

sudo firewall-cmd --permanent --zone=trusted --add-source=172.101.0.0/16

host.docker.internal

docker for Mac, docker for Windowsでサポートされている、コンテナからホストのネットワークにアクセスするための特殊なドメイン。
macが開発者の主流になっているので、気軽にプロジェクトで使われ、その度にlinuxユーザーは悩みを抱える。

Support host.docker.internal DNS name to host
Support host.docker.internal in dockerd on Linux
[RFD] add configuration option to add host.docker.internal by default

これらのissueによって最終的にはlinuxでも host.docker.internal が使えるようになる予定ですが、リリースされるまでまだ少し掛かりそうなのでWorkaroundを記載しておきます。
というより、作業内容としては上述の通りなので、解説を書きます。

docker-compose.override.yaml

このファイルはdocker-composeコマンドを実行した時に自動で読まれるので、レポジトリに含めたくない自分専用の設定などを書く際に重宝します。
ただし、-fオプションを使用する際は自動では読まれないので、その際にはこのファイルも一緒に指定する必要があります。

extra_hosts

コンテナの /etc/hosts に内容を追記します。

networks

全てのコンテナは特に設定をしなければdefaultという名前のnetworkに属するので、ここに設定を書けば全てのコンテナに自動で反映されます。
ここで設定しているのは、default networkのサブネットです。普通であればnetworkのサブネットは、既存のnetworkとかぶらないように自動で選ばれますが、今回は固定したいため手動で選び設定します。
ホストは全てのnetworkに属し、そのIPは「サブネットマスクの一番下位のbitを1にしたもの」になるようです。(実際に試してそうっぽいと言うだけでドキュメントにそういう記載を見つけたわけではないので、もしかしたらそうならないケースもあるかもしれません。)
なので、このIPをextra_hostsに指定すればドメインを割り当てられるというわけです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxでApache2.4(httpd 2.4.43)+PHP7.4をソースコンパイルしてWebサーバー構築 - 2.PHP導入編

前提と準備

Linuxサーバー構築の記事

前回はApache httpd 2.4.43をソースコンパイルでWebサーバーで構築しましたが、今回は、前回に引き続き、ApacheにWebアプリサーバーの基幹であるPHP 7.4をソースコンパイルで導入します(⑅•ᴗ•⑅)

環境

  • Webサーバープログラム:Apache 2.4.43 + PHP 7.4.6(ソースコンパイル)
  • クライアント:Windows10 Pro
  • サーバーのアーキテクチャ:x64(動作はHyper-Vの第2世代で確認) Linuxのディストリビューション:CentOS 8.1 / openSUSE 15.1 Leap / Ubuntu 20.04(すべて64bit)

前提

  • ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
  • どのディストリビューションでも、ファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)
  • 前回の記事のApache導入を完了していること(動作が確認できて、Webサーバーとして構築されていること)

サーバー条件

IPアドレス

  • クライアント:192.168.1.11
  • Webサーバー:192.168.1.18(どのディストリビューションでも同じIPアドレスで検証)
  • 所属ネットワークセグメント:192.168.1.0/24 Webサーバー.png

パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)

  • zlib-1.2.11.tar.gz
  • apr-1.7.0.tar.gz
  • apr-util-1.6.1.tar.gz
  • mysql80-community-release-el8-1.noarch.rpm (CentOS 8.1)
  • mysql80-community-release-sl15-3.noarch.rpm (openSUSE 15.1)
  • mysql-apt-config_0.8.15-1_all.deb (Ubuntu 20.04)
  • oniguruma-devel-6.8.2-1.el8.x86_64.rpm (CentOS 8.1)
  • httpd-2.4.43.tar.gz
  • php-7.4.6.tar.gz

それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。

ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。

作業手順

PHPのインストール

PHPのソースコンパイルに必要なライブラリを導入

CentOS8.1
# dnf -y install libxml2 libxml2-devel sqlite-devel
# dnf -y install oniguruma-devel-6.8.2-1.el8.x86_64.rpm
openSUSE15.1
# zypper -n install libxml2-tools libxml2-devel sqlite3-devel oniguruma-devel
Ubuntu20.04
# apt-get -y install libxml2 libxml2-dev libsqlite3-dev libonig-dev

PHP7.3までは、SQLiteと鬼車のライブラリを使わなくてもマルチバイト文字列を扱うようインストールができたのですが、PHP7.4ではソースコンパイルで必須となりました。

CentOS 8.1のみ、鬼車ライブラリ(oniguruma-devel-6.8.2-1.el8.x86_64.rpm)はデフォルトパッケージには存在しないため、CentOSパッケージのダウンロードページから持ってきました。

2020年6月現在:
http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/oniguruma-devel-6.8.2-1.el8.x86_64.rpm

PHPのソースコンパイル

コンパイルには20~30分前後かかる見込みです。Apacheより規模が大きいので、コンパイル中はコーヒー1杯で休憩をはさんだほうがいいかもしれません(*˘︶˘*).。.:*♡

# cd [php-7.4.6.tar.gzが置いてあるディレクトリ]
# tar xvzf php-7.4.6.tar.gz
# cd php-7.4.6/
# ./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」が時間がかかるコマンドです。
途中でエラーがなければコンパイル完了です。
なお、CentOS 8.1とUbuntu 20.04でmake testで私がテストしたところ、なんとバグは一つもなかったのです( ๑・∞・๑ ) …OSと相性がいいのかもしれません
php_test_fail.png

PHPのインストール

コンパイルが完了したら、インストールします。

CentOS8.1・Ubuntu20.04
# 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/
openSUSE15.1
# 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/lib64/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/lib64/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/」のように、用途に応じて複数の配置場所へ配置されます。openSUSE 15.1の場合は「/usr/local/lib64/php/」に配置されるものもあります。
また、この時点で、PHPのDLL(ダイナミックリンクライブラリ、外部拡張アプリケーションに該当する)は自動的にApacheのフォルダに配備されます

次に、PHPの環境設定ファイルのコピーを行います。
まずはphp.iniをPHPのライブラリフォルダ/usr/local/lib(openSUSEの場合はlib64)/にコピーします。

CentOS8.1・Ubuntu20.04
# 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 pkgconfig
openSUSE15.1
# cp php.ini-development /usr/local/lib64/php.ini
# ls -l /usr/local/lib64
合計 72
drwxr-xr-x 1 root root   338  6月 25 16:59 build
drwxr-xr-x 1 root root    42  6月 25 16:59 extensions
-rw-r--r-- 1 root root 72278  6月 25 17:01 php.ini

Apache側の設定

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の文字コードや参照ライブラリの設定を変えます。

PHPをコンパイルインストールした際に、ディストリビューションによって、php.iniの格納ディレクトリが違います。openSUSEのみ、/usr/local/lib64/にPHPが含まれていますので、ライブラリフォルダ「lib」の違いが紛らわしいです

CentOS8.1・Ubuntu20.04
# vi /usr/local/lib/php.ini
openSUSE15.1
# vi /usr/local/lib64/php.ini
php.ini
# 内容が長いので、一部修正するもののみ、修正後のもののみを記載します。セミコロン「;」は外します。「;」外すだけの行も含めて記載されています
output_buffering = On
default_charset = "UTF-8"
 [CentOS 8.1・Ubuntu 20.04] include_path = ".:/usr/local/include/php:/usr/local/lib/php"
 [openSUSE 15.1] include_path = ".:/usr/local/include/php:/usr/local/lib64"
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 = none

PHPの動作確認

PHP確認用のページ

まずは確認用のPHPページを作ります。

# vi /usr/local/apache2/htdocs/phpi.php
phpi.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で起動していることを確認します。
phpinfo.png
PHPが正しく認識できました!!(*´꒳`*)

pdo.png
PDOもちゃんと認識できています。そうしないとMySQLとSQLiteが使えないからね…( ´ •̥ ̫ •̥ ` )

susephpi.png

openSUSE 15.1の場合だと、php.iniの場所が「/usr/local/lib64」となって認識されていることがわかります。

次回

MySQLを導入して、PHPのWebアプリサーバーがデータベースを利用できるようにします

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon EC2(Amazon linux)から直接S3へのファイルコピー

Amazon EC2(Linux)から直接S3へファイルコピー

 AWS環境で何か検証している際にEC2内のデータファイルを別環境へエクスポートしたいことがあるかと思います。(私は結構ありますが皆さんどうなのでしょうね...)
 EC2がWindows server OSならブラウザーが使えるのでBox等にUpするとかWebメールに添付してとか色々やりようはあると思いますがLinux OSだとどうしよう(´・ω・`)ってなります。
 そこでAWS CLIを使って、EC2から直接S3にアップロードして、S3のコンソール画面から別環境にダウンロードするという方法を検証したいと思います。

実現したいこと

やりたいこと.png

 EC2(Linux)内のデータファイルをS3へエクスポートして、S3コンソール画面からDLできるようにしたい

手順

 1. EC2をデプロイ
 2. EC2内にディレクトリとファイルを作成
 3. EC2にS3アップロードのためのロールをアタッチ
 4. コピー先のS3バケットを作成
 5. AWS CLIでS3へデータコピー
 

やってみた

 まずEC2をデプロイして、SSHでログインします。そしてディレクトリを作成して、S3へコピーするテストファイルを作成します。
 ※EC2のデプロイ手順は各所で色々情報が出ておりますので、ここでは割愛します

#root にユーザ切替
 sudo su root 
#情報を最新にアップロードします
 yum -y update
#/home にディレクト(/test-share)を作成
 cd /home
 mkdir /test-share
 cd /test-share
#テストファイル(test.txt)を作成
 touch test.txt
#ファイルが作成されたか確認
 ls

 これで、S3へコピーするテストファイルの準備はOKです。

 デプロイしたEC2ですが、今の状態はS3へアクセスする権限(ロール)をもっていないのでロールをアタッチする必要があります。

 ロールの作り方は
 AWS コンソール画面からIAMにアクセスして、「ロール」をクリック
 スライド2.PNG

次に「ロールの作成」をクリック
スライド3.PNG

一般的なユースケースで「EC2」を選択
スライド4.PNG

ロールに割り当てるポリシーを選択
ポリシーのフィルターにS3と入力して、表示されるポリシーの中で
今回はS3へのアクセス(アップロード、ダウンロード、閲覧)したいので[AmzzonS3FullAccess] を選択します。

スライド5.PNG

必要に応じて、タグ付け(今回はタグは設定してないです)
スライド6.PNG

ロール名を任意に設定して、「作成」
スライド7.PNG

ロールが作成できたらEC2へアタッチ
EC2のコンソール画面で対象インスタンスを選択し、「アクション」-「インスタンスの設定」ー「IAMロールの割り当て/置き換え」
S3_Qiita用.png

対象のインスタンスIDとロールを割り当てして、「適用」
S3_ロール割り当て_Qiita用.png

 これでEC2がS3へアクセスするロールをアタッチできました。

 次にデータのコピー先のS3バケット(test-20200624-folder)を作成します。
S3のコンソール画面へアクセスして、「バケットを作成する」
スライド8.PNG

 バケット名に「test-20200624-folder」とリージョン(今回はアジアパシフィック)を入力して、「次へ」
スライド9.PNG

 バケットの設定をするのですが、今回は特に設定を変えるところはないのでこのまま「次へ」
スライド10.PNG

 ブロックパブリックアクセスにチェックが入っていることを確認して「次へ」
スライド11.PNG

 ※別に今回は試験環境なので、パブリックアクセスはブロックは不要ですが、デフォルトはブロックなので。
 
これで「バケットの作成」まで進めてもらえれば、S3側の準備もOKです。

 ロールをアタッチできたら、AWS CLIでS3へデータコピーするコマンドを入力します。

#再度EC2へSSHでログインして、root に切替えます
 sudo su root
#テストファイルがあるディレクトリまで移動
 cd /home /test-share
#aws cli でS3へデータコピー
 aws s3 cp /test.txt s3://test-20200624-folder
※EC2にはaws cliが標準でインストールされているので、yumコマンドでインストールする必要はないです
#コマンド実行後の upload: ./test.txt to s3://test-0624-folder/test.txt と表示されればOKです
#S3にデータがあるかを確認
aws s3 ls s3://test-20200624-folder
#2020-06-24 06:59:35          0 test.txt のように表示ささればOKです

最後にS3コンソール画面から「test.txt」をDLできるか確認していきます。
S3コンソール画面へアクセスし、対象のバケットを確認すると
S3_コンソールQiita用.png

test.txtがコピーされていることが確認できました!
あとは「アクション」から「ダウンロード」を選択すれば、別環境へファイルのエクスポート完了です。

最後に

同じ内容の記事が各所ありますが、EC2のロールをアタッチする旨の説明がなかったりで手順通りにしてもエラーになったりしたので、備忘録および初心者の皆さんのお役に立てればと思います。

AWS CLIを利用してEC2からS3へデータコピーだけなく、EC2の特定のディレクトとS3バケットのフォルダを同期させたりと色々と応用ができます。
EC2にルートCA機能を持たせて、作った証明書をエクスポートしたり、検証用のログファイルの送信で利用できれば便利ですねd(`・ω・’)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxでApache2.4(httpd 2.4.43)をソースコンパイルしてWebサーバーを構築する - 1.Apache導入編

前提と準備

Linuxサーバー構築の記事

最初に個人経営や中小企業から、PCのファイルを共有することから、中古PCでもラズパイでも小さなPCでサーバー構築できるものとして、まずはSambaを使ってファイルサーバーを構築してみましたが、今回はApacheでWebサーバーで構築します(⑅•ᴗ•⑅)

ソースコードでコンパイルする意味

Apacheをどのディストリビューションでも同じように設定しやすいし、必要なバージョンを用意できるからです(パッケージの標準コマンドだけだと、そのディストリビューションのバージョンで変動する)。

しかし全部のパッケージをソースコンパイルすると、その大本のライブラリを全部探し回ることになるので、ApacheやPHPなど、どうしても固定して稼働したいものに限って、ソースコンパイルし、makeに必要なものについては、dnfやaptなどの標準パッケージコマンドで対応しています

環境

  • Webサーバープログラム:Apache 2.4.43(ソースコンパイル)
  • クライアント:Windows10 Pro
  • サーバーのアーキテクチャ:x64(動作はHyper-Vの第2世代で確認) Linuxのディストリビューション:CentOS 8.1 / openSUSE 15.1 Leap / Ubuntu 20.04(すべて64bit)

前提

  • OSは最小限のインストール。また、最新の状態でOSをアップデートしていること
  • ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
  • どのディストリビューションでも、ファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)
  • CentOSについては、SELinuxを無効(/etc/selinux/config編集後は再起動も必要)。
CentOS8.1
# vi /etc/selinux/config
/etc/selinux/config
SELINUX=disabled
CentOS8.1
# reboot

サーバー条件

IPアドレス

  • クライアント:192.168.1.11
  • Webサーバー:192.168.1.18(どのディストリビューションでも同じIPアドレスで検証)
  • 所属ネットワークセグメント:192.168.1.0/24 Webサーバー.png

パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)

  • zlib-1.2.11.tar.gz
  • apr-1.7.0.tar.gz
  • apr-util-1.6.1.tar.gz
  • mysql80-community-release-el8-1.noarch.rpm (CentOS 8.1)
  • mysql80-community-release-sl15-3.noarch.rpm (openSUSE 15.1)
  • mysql-apt-config_0.8.15-1_all.deb (Ubuntu 20.04)
  • oniguruma-devel-6.8.2-1.el8.x86_64.rpm (CentOS 8.1)
  • httpd-2.4.43.tar.gz
  • php-7.4.6.tar.gz

それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。

ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。

作業手順

準備

makeやcmake、パッケージ解凍機能のインストール

CentOS8.1
# dnf -y install make cmake tar bzip2

GCCとC++コンパイラのインストール

CentOS8.1
# dnf -y install gcc gcc-c++

zlibのソースインストール

zlibの配置場所はデフォルトのまま変えないでインストールしました。

# cd [zlibの書庫ファイルが置いてあるディレクトリ]
# tar zxvf zlib-1.2.11.tar.gz
# cd zlib-1.2.11/
# ./configure
# make
# make install

Apacheをコンパイルするために必要なパッケージをディストリビューション標準パッケージコマンドでインストール

PerlやSSLのライブラリなどをインストールすることで、Apacheで必要な機能をそろえることができます
注意:面倒くさくても実行しないと、パッケージがない、とエラーが出てコンパイルが中止されるんです(´•ω•̥`)

CentOS8.1
# dnf -y install ncurses-devel perl libaio libaio-devel perl-Data-Dumper expat-devel pcre pcre-devel openssl-devel

APRとそのユーティリティーライブラリをインストール

APRは/opt/apr-1.7.0に、APR-Utilは/opt/apt-util-1.6.1にライブラリをインストールします

# cd [APR 1.7.0の書庫ファイルが置いてあるディレクトリ]
# 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 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
# sudo make install 

Apache 2.4のソースコンパイルのインストール

さて、ここからが本番です。この作業は結構時間がかかりました(私のPCのHyper-Vで、たぶん30分かな)

configureとmake

# cd [Apache httpdが置いてあるディレクトリ]
# tar xvzf httpd-2.4.43.tar.gz
# cd httpd-2.4.43/
# ./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.csr

SSL鍵を作成するプロセスで、組織のプロフィールを入力する対話もありますが、以下の入力で問題なく証明書は作成できます

# 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 city

server.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.service
httpd.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を指定します。

firewalldの設定

続いて、firewalldの設定で、ポート80(http)と443(httpd)を受け付けます。
なお、前提の通り、サーバーとクライアントは192.168.1.0/24のネットワークに属しているので、それ以外の外部からのアクセスは受け付けないので、以下のようにrich ruleで許可します。

# 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 --reload

起動と動作確認

それでは、起動します。enableでの常時起動有効化&statusで「Active」「Running」になっていることを確認。

# systemctl start httpd
# systemctl enable httpd
# systemctl status httpd

apachect.png
上記の写真のようになれば、起動成功です。
Windowsクライアント側から、ブラウザでhttps://[LinuxサーバーのIPアドレス]/を入力して確認します。

ここではLinuxのWebサーバーは192.168.1.18なので、https://192.168.1.18にて。
もちろん証明書は信頼された機関発行ではないので、プライバシーエラーになります;;その際は「そのままアクセスする」を選んで先に進みます(ChromeやFirefoxでふるまいは違うけど。。)

itwks.png

成功しました!!( ˶˙ᵕ˙˶ )

今後すること

さらにPHPとMySQLを導入して、Webアプリサーバーの構築も後日掲載予定です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxでApache2.4(httpd 2.4.43)+PHP7.4をソースコンパイルしてWebサーバー構築 - 1.Apache導入編

前提と準備

Linuxサーバー構築の記事

最初に個人経営や中小企業から、PCのファイルを共有することから、中古PCでもラズパイでも小さなPCでサーバー構築できるものとして、まずはSambaを使ってファイルサーバーを構築してみましたが、今回はApacheでWebサーバーで構築します(⑅•ᴗ•⑅)

ソースコードでコンパイルする意味

Apacheをどのディストリビューションでも同じように設定しやすいし、必要なバージョンを用意できるからです(パッケージの標準コマンドだけだと、そのディストリビューションのバージョンで変動する)。

しかし全部のパッケージをソースコンパイルすると、その大本のライブラリを全部探し回ることになるので、ApacheやPHPなど、どうしても固定して稼働したいものに限って、ソースコンパイルし、makeに必要なものについては、dnfやaptなどの標準パッケージコマンドで対応しています

環境

  • Webサーバープログラム:Apache 2.4.43(ソースコンパイル)
  • クライアント:Windows10 Pro
  • サーバーのアーキテクチャ:x64(動作はHyper-Vの第2世代で確認) Linuxのディストリビューション:CentOS 8.1 / openSUSE 15.1 Leap / Ubuntu 20.04(すべて64bit)

前提

  • OSは最小限のインストール。また、最新の状態でOSをアップデートしていること
  • ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
  • どのディストリビューションでも、ファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)
  • CentOSについては、SELinuxを無効(/etc/selinux/config編集後は再起動も必要)。
CentOS8.1
# vi /etc/selinux/config
/etc/selinux/config
SELINUX=disabled
CentOS8.1
# reboot

サーバー条件

IPアドレス

  • クライアント:192.168.1.11
  • Webサーバー:192.168.1.18(どのディストリビューションでも同じIPアドレスで検証)
  • 所属ネットワークセグメント:192.168.1.0/24 Webサーバー.png

パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)

  • zlib-1.2.11.tar.gz
  • apr-1.7.0.tar.gz
  • apr-util-1.6.1.tar.gz
  • mysql80-community-release-el8-1.noarch.rpm (CentOS 8.1)
  • mysql80-community-release-sl15-3.noarch.rpm (openSUSE 15.1)
  • mysql-apt-config_0.8.15-1_all.deb (Ubuntu 20.04)
  • oniguruma-devel-6.8.2-1.el8.x86_64.rpm (CentOS 8.1)
  • httpd-2.4.43.tar.gz
  • php-7.4.6.tar.gz

それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。

ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。

作業手順

準備

makeやcmake、パッケージ解凍機能のインストール

CentOS8.1
# dnf -y install make cmake tar bzip2
openSUSE15.1
# zypper -n install make cmake tar bzip2
Ubuntu20.04
# apt-get -y install make cmake tar bzip2

GCCとC++コンパイラのインストール

CentOS8.1
# dnf -y install gcc gcc-c++
openSUSE15.1
# zypper -n install gcc gcc-c++
Ubuntu20.04
# apt-get -y install gcc build-essential

zlibのソースインストール

zlibの配置場所はデフォルトのまま変えないでインストールしました。

# cd [zlibの書庫ファイルが置いてあるディレクトリ]
# tar zxvf zlib-1.2.11.tar.gz
# cd zlib-1.2.11/
# ./configure
# make
# make install

Apacheをコンパイルするために必要なパッケージをディストリビューション標準パッケージコマンドでインストール

PerlやSSLのライブラリなどをインストールすることで、Apacheで必要な機能をそろえることができます
注意:面倒くさくても実行しないと、パッケージがない、とエラーが出てコンパイルが中止されるんです(´•ω•̥`)

CentOS8.1
# dnf -y install ncurses-devel perl libaio libaio-devel perl-Data-Dumper expat-devel pcre pcre-devel openssl-devel
openSUSE15.1
# zypper -n install ncurses-devel perl libaio1 libaio-devel perl-Data-Dump libexpat-devel pcre pcre-devel libopenssl-devel
Ubuntu20.04
# apt-get -y install libncurses5-dev perl libaio1 libaio-dev libexpat1-dev libpcre3 libpcre3-dev libssl-dev

APRとそのユーティリティーライブラリをインストール

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 install  

Apache 2.4のソースコンパイルのインストール

さて、ここからが本番です。この作業は結構時間がかかりました(私のPCのHyper-Vで、たぶん20分かな)

configureとmake

# cd [httpd-2.4.43.tar.gzが置いてあるディレクトリ]
# tar xvzf httpd-2.4.43.tar.gz
# cd httpd-2.4.43/
# ./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.csr

SSL鍵を作成するプロセスで、組織のプロフィールを入力する対話もありますが、以下の入力で問題なく証明書は作成できます

# 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 city

server.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.service
httpd.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を指定します。

firewalldの設定

続いて、firewalldの設定で、ポート80(http)と443(httpd)を受け付けます。
なお、前提の通り、サーバーとクライアントは192.168.1.0/24のネットワークに属しているので、それ以外の外部からのアクセスは受け付けないので、以下のようにrich ruleで許可します。

# 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 --reload

起動と動作確認

それでは、起動します。enableでの常時起動有効化&statusで「Active」「Running」になっていることを確認。

# systemctl start httpd
# systemctl enable httpd
# systemctl status httpd

apachect.png
上記の写真のようになれば、起動成功です。
Windowsクライアント側から、ブラウザでhttps://[LinuxサーバーのIPアドレス]/を入力して確認します。

ここではLinuxのWebサーバーは192.168.1.18なので、https://192.168.1.18にて。
もちろん証明書は信頼された機関発行ではないので、プライバシーエラーになります;;その際は「そのままアクセスする」を選んで先に進みます(ChromeやFirefoxでふるまいは違うけど。。)

itwks.png

成功しました!!( ˶˙ᵕ˙˶ )

次回

PHPを導入して、Webアプリサーバーの基盤を掲載します

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2でsudo実行時エラーが出るようになった話 sudo: /usr/bin/sudo be owned by uid 0 and the setuid bit set

はじめに

誤って /bin 以下のパーミッションを変更してしまい、sudoコマンド実行時にエラーが出るようになった。
(確か)rootユーザでのログインもできなくなった。

結論

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-sudo-commands/
上記を参考に、AWS EC2コンソールのインスタンス設定で、スクリプト設定をすると、root:rootになって復旧。

詳細

流れでコマンドを打ってる際、chown -R hoge bin/ のつもりが /binを指定してしまった…

コマンドのスペルミスなどの打ち間違いを補完する方法はあるが、間違っていないので今回のケースは防げない。
こんなミスをするユーザにはsudo権限を与えないなど、権限を絞ることもできるが、自分がサーバ管理者であった。

「気をつける」レベルの対策になってしまうが、下記を意識していきたいと思う

  • 変更を加えるコマンド実行時は、絶対パス指定しない
  • コマンド実行前に、かならず見直す

おわりに

AWSの中の人、復旧方法を用意しておいてくれて、ありがとうございます:sob:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu 16.04にパペットマスターとクライアントをインストールする

Puppetは、自動化からアップデートインストールまで、様々なアプリケーションに対応したオープンソースの設定管理システムです。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

序章

Puppetは、自動化からアップデートインストールまで幅広く利用できるオープンソースの設定管理システムです。Rubyで書かれており、UnixやWindowsのようなOSの設定を管理するために特別に設計されています。1台のサーバから数千台の物理サーバや仮想サーバを一元管理して簡単に導入・管理することができます。

Puppetは、クライアントサーバ型のアーキテクチャでもスタンドアロン型のアーキテクチャでも使用できます。クライアント・サーバ・アーキテクチャでは、サーバはマスターとして、クライアントはエージェントとして知られています。Puppetには、EnterpriseとOpen sourceの2つのバージョンがあります。どちらも多くのLinuxディストリビューションとWindowsをサポートしています。Puppetは、システム管理者が反復的な作業に費やす時間を削減し、より大きなビジネス価値を提供するプロジェクトに集中できるようにすることで、システム管理者を支援します。

特徴

  • PuppetはIdempotencyをサポートしており、同じマシン上で同じ設定を複数回実行することが容易になります。
  • 同じ問題を解決している全員のタスクを重複して実行する必要がなくなります。
  • すべてのタスクはネイティブコードで書かれており、簡単に共有することができます。
  • 繰り返し可能な変更を自動的に行うことができます。
  • 必要に応じて拡張機能を追加することで、余分な機能を追加することができます。

このガイドでは、オープンソースのPuppetをUbuntu 16.04サーバ上で、Alibaba Cloud Elastic Compute Service (ECS)インスタンスを使用してクライアント/サーバアーキテクチャでインストールし、設定する手順を説明します。

前提条件

  • Ubuntu 16.04がインストールされたパペットマスター用のAlibaba Cloud ECSインスタンス。
  • Ubuntu 16.04がインストールされたPuppetエージェント用のAlibaba Cloud ECSインスタンス。
  • パペットマスターに静的IPアドレス192.168.0.103が設定されている。
  • パペットエージェントに192.168.0.104の静的IPアドレスが設定されている。
  • パペットマスターには最低4GBのメモリとデュアルコアCPUが必要。
  • 両方のインスタンスにsudo権限を持つ非rootユーザが設定されている。

ホスト名の設定

始める前に、Server ノードと agent ノードで /etc/hosts と /etc/hostname ファイルを設定して、これらのファイルが相互に通信できるようにする必要があります。

Serverノードで/etc/hostsと/etc/hostnameファイルを開き、以下の変更を行います。

sudo nano /etc/hosts

ファイルの最後に以下の行を追加します。

192.168.0.0.103 puppet-server

sudo nano /etc/hostname

以下のようにファイルを変更します。

puppet-server

保存し、終了したらファイルを閉じます。

Agentノードで/etc/hostsと/etc/hostnameファイルを開き、以下の変更を行います。

sudo nano /etc/hosts

ファイルの最後に以下の行を追加します。

192.168.0.0.103 puppet-server

sudo nano /etc/hostname

以下のようにファイルを変更します。

puppet-agent

終了したら保存して閉じてください。

Puppetのインストール

Ubuntu 16.04のデフォルトリポジトリではPuppetサーバーは利用できません。そのため、MasterノードとAgentノードの両方にPuppet Labリポジトリを追加する必要があります。

それぞれのノードで以下のコマンドを実行して、Puppetのリポジトリをダウンロードしてインストールします。

wget https://apt.puppetlabs.com/puppetlabs-release-pc1-xenial.deb
sudo dpkg -i puppetlabs-release-pc1-xenial.deb
sudo apt-get update -y

次に、以下のコマンドでマスターノードにPuppetサーバパッケージをインストールします。

sudo apt-get install puppetserver -y

Puppetサーバをインストールした後、メモリの割り当てを設定する必要があります。マスターノードのメモリ量に応じてメモリ使用量をカスタマイズすることをお勧めします。これは/etc/default/puppetserverファイルを編集することで行うことができます。

sudo nano /etc/default/puppetserver

サーバーの容量に合わせて行を変更してください。

以下の行を変更してください。

JAVA_ARGS="-Xms2g -Xmx2g -XX:MaxPermSize=256m”から

JAVA_ARGS="-Xms512m -Xmx512m”へ。

保存してファイルを閉じ、以下のコマンドでPuppetサーバを起動し、起動時に起動できるようにします。

sudo systemctl start puppetserver
sudo systemctl enable puppetserver

Puppetサーバーの状態は以下のコマンドで確認できます。

sudo systemctl status puppetserver

すべてが正常な場合は、以下のような出力が表示されるはずです。

● puppetserver.service - puppetserver Service
   Loaded: loaded (/lib/systemd/system/puppetserver.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2017-10-28 18:47:26 IST; 12min ago
  Process: 887 ExecStart=/opt/puppetlabs/server/apps/puppetserver/bin/puppetserver start (code=exited, status=0/SUCCESS)
 Main PID: 963 (java)
   CGroup: /system.slice/puppetserver.service
           └─963 /usr/bin/java -Xms256m -Xmx256m -Djava.security.egd=/dev/urandom -XX:OnOutOfMemoryError=kill -9 %p -cp /opt/puppetlabs/server/

Puppet Agentのインストール

これでPuppetサーバーは稼働しています。いよいよAgentノードにPuppet agentをインストールする時が来ました。

Puppet agentをインストールする前に、AgentノードにPuppet Labリポジトリがインストールされていることを確認してください。次に、以下のコマンドを実行するだけでPuppet agentをインストールします。

sudo apt-get install puppet-agent -y

Puppet Agentをインストールしたら、puppet設定ファイルを編集し、puppetマスター情報を設定する必要があります。

これは以下のコマンドで行うことができます。

sudo nano /etc/puppetlabs/puppet/puppet.conf

以下の行を追加します。

[main]
certname = puppet-agent
server = puppet-server
environment = IT

保存してファイルを閉じ、以下のコマンドでPuppet Agentサービスを起動し、起動時に起動できるようにします。

sudo systemctl start puppet
sudo systemctl enable puppet

パペットサーバー上のパペットエージェント証明書に署名する

Puppetが初めてAgentノードを実行するとき、Puppetはパペットサーバに証明書署名要求を送信します。クライアント・サーバ型のアーキテクチャでは、エージェントノードを制御するために、パペットマスターサーバが各エージェントノードの証明書要求を承認する必要があります。

パペットサーバ上で、以下のコマンドですべての署名されていない証明書要求をリストアップします。

sudo /opt/puppetlabs/bin/puppet cert list

エージェントノードのホスト名で1つのリクエストが表示されているはずです。

"puppet-agent" (SHA256) 7C:28:E8:AF:09:23:55:19:AF:C1:EE:C3:66:F2:02:73:AD:7F:53:17:28:CE:B0:26:AE:C7:6C:67:16:05:6F:2E

次に、以下のコマンドで証明書要求に署名します。

sudo /opt/puppetlabs/bin/puppet cert sign puppet-agent

以下のような出力が表示されるはずです。

Signing Certificate Request for:
  "puppet-agent" (SHA256) 7C:28:E8:AF:09:23:55:19:AF:C1:EE:C3:66:F2:02:73:AD:7F:53:17:28:CE:B0:26:AE:C7:6C:67:16:05:6F:2E
Notice: Signed certificate request for puppet-agent
Notice: Removing file Puppet::SSL::CertificateRequest puppet-agent at '/etc/puppetlabs/puppet/ssl/ca/requests/puppet-agent.pem'

これでパペットマスターサーバーはAgentノードと通信して制御できるようになりました。複数のノードの証明書要求に一度に署名したい場合は、以下のコマンドを実行します。

sudo /opt/puppetlabs/bin/puppet cert sign —all

PuppetマスターがPuppet Agent証明書に署名したら、Puppet Agentノードで以下のコマンドを実行してテストします。

sudo /opt/puppetlabs/bin/puppet agent —test

すべてが正しく行われていれば、以下のような出力が表示されるはずです。

Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent
Info: Applying configuration version '1509200872'
Notice: Applied catalog in 0.09 seconds

エージェントノードにApacheをインストールするためにPuppetサーバを設定する

これでPuppetマスター、エージェントノードともに設定が完了し、機能するようになりました。いよいよPuppetを検証してみましょう。

そのために、AgentノードにApacheウェブサーバをインストールするためのマニフェストファイルを作成します。マニフェストはクライアントの設定を含むデータファイルです。デフォルトでは、マニフェストファイルは /etc/puppetlabs/code/environments/production/manifests/directory.にあります。

マニフェストファイルの作成に進む前に、puppetlabs-apacheモジュールをインストールする必要があります。

Puppetマスターノードで、以下のコマンドを実行して、puppetlabs-apacheモジュールをインストールします。

sudo /opt/puppetlabs/bin/puppet module install puppetlabs-apache

以下のような出力が表示されるはずです。

Notice: Preparing to install into /etc/puppetlabs/code/environments/production/modules ...
Notice: Downloading from https://forgeapi.puppet.com ...
Notice: Installing -- do not interrupt ...
/etc/puppetlabs/code/environments/production/modules
└─┬ puppetlabs-apache (v2.3.0)
  ├── puppetlabs-concat (v4.1.0)
  └── puppetlabs-stdlib (v4.20.0)

次に、以下のコマンドでPuppetマスター上にマニフェストファイルを作成します。

sudo nano /etc/puppetlabs/code/environments/production/manifests/site.pp

以下の行を追加します。

node 'puppet-agent' {
  class { 'apache': }             # use apache module
  apache::vhost { 'localhost':  # define vhost resource
    port    => '80',
    docroot => '/var/www/html'
  }
}

上記の設定では、Apacheをインストールし、localhostというバーチャルホストを設定し、80番ポートでリスニングし、Agentノード上にドキュメントルート/var/www/htmlを持つようにします。

さて、Agentノード上で以下のコマンドを実行して、マニフェストファイルからすべての設定を取得します。

sudo /opt/puppetlabs/bin/puppet agent —test

すべてが成功した場合、以下のような出力が表示されるはずです。


Notice: /Stage[main]/Apache/Apache::Vhost[default]/File[15-default.conf symlink]/ensure: created
Info: /Stage[main]/Apache/Apache::Vhost[default]/File[15-default.conf symlink]: Scheduling refresh of Class[Apache::Service]
Notice: /Stage[main]/Main/Node[puppet-agent]/Apache::Vhost[localhost]/Concat[25-localhost.conf]/File[/etc/apache2/sites-available/25-localhost.conf]/ensure: defined content as '{md5}05a8b8c6772009021086814bdf8c985e'
Info: Concat[25-localhost.conf]: Scheduling refresh of Class[Apache::Service]
Notice: /Stage[main]/Main/Node[puppet-agent]/Apache::Vhost[localhost]/File[25-localhost.conf symlink]/ensure: created
Info: /Stage[main]/Main/Node[puppet-agent]/Apache::Vhost[localhost]/File[25-localhost.conf symlink]: Scheduling refresh of Class[Apache::Service]
Info: Class[Apache::Service]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Apache::Service/Service[httpd]: Triggered 'refresh' from 1 events
Notice: Applied catalog in 53.11 seconds
`

おめでとうございます。これで Apache が Agent ノードにインストールされ、実行されています。

結論

このチュートリアルでは、本番環境にPuppetサーバーを簡単にインストールし、ITインフラ全体を簡単に管理することができます。Puppetの詳細については、Puppetの公式ドキュメントページを参照してください。その他のチュートリアルは、Alibaba Cloud Getting Startedチャンネルにも掲載されています。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Linux(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)の社内サーバー構築の基本!Sambaでファイルサーバー

コロナウイルスの影響で、世界経済が崩壊しており、規模関係なくテレワークの導入も相次いでいますが、小規模組織からPCを使った業務で、部屋の中のLAN内でファイルを共有することから、まずは始めたいと思います( ˶˙ᵕ˙˶ )

基本はLinux+Sambaによる、LAN内のファイルサーバーで、組織内で複数のPCでファイルを共有することから始めましょう!簡単なため、Linux各ディストリビューションに用意されているSambaをインストールして、Linuxによるファイルサーバーを構築します

前提と準備

環境

  • ファイルサーバープログラム:Samba(Linuxパッケージ標準のsmbd)
  • クライアント:Windows10 Pro
  • サーバーのアーキテクチャ:x64(動作はHyper-Vの第2世代で確認) Linuxのディストリビューション:CentOS 8.1 / openSUSE 15.1 Leap / Ubuntu 20.04(すべて64bit)

前提

  • ユーザーはrootでインストールするものとする。キャプチャ画面では管理者adminを作成し、そこからsudoでrootと同様のコマンドを実行する
  • どのディストリビューションでも、ファイアウォールはfirewalldを使うものとする(ディストリビューション独自のファイアウォールコマンドは使用しない)
  • OSのインストールについては省略する
  • LANのネットワークセグメントは192.168.1.0/24に属するものとする
  • CentOSについては、SELinuxを無効にします(/etc/selinux/config編集後は再起動も必要)。
CentOS8.1
# vi /etc/selinux/config
/etc/selinux/config
SELINUX=enforcing
→ SELINUX=disabled に変更
CentOS8.1
# reboot

サーバー条件

以下の条件で、Sambaでファイルサーバーを組んでみました٩(.´͈ ᵕ `͈ .♡)۶

IPアドレス

  • クライアント:192.168.1.11
  • Linuxサーバー:192.168.1.18(どのディストリビューションでも同じIPアドレスを使う)
  • 所属ネットワークセグメント:192.168.1.0/24

サーバー図.png

ファイルサーバー条件

  • 例として、ファイルサーバースペースで作成するセクション名を「kazumi75kitty」とする
  • 例として、ファイルサーバースペースとして使用するLinuxサーバー上のディレクトリは /mnt/miura/ とし、読み書きともにOKとする

作業手順

OSのアップデート

これはもちろんのことです!アップデートは事前に実行

CentOS8.1
# dnf -y upgrade
openSUSE15.1
# zypper -n update
Ubuntu20.04
# apt-get -y update

アップデートが完了したら、Linuxを再起動します。

Sambaの導入

Sambaのインストール

Linux各ディストリビューションのパッケージからSambaをインストールします。

CentOS8.1
# dnf -y install samba
openSUSE15.1
# zypper -n install samba
Ubuntu20.04
# apt-get -y install samba

Sambaを利用するユーザーの作成

新たにSambaファイルサーバーを利用するLinuxユーザーを新規に作成。
今回は例として「shonan」というユーザー名でファイルサーバーを使うものとします。

# useradd -m shonan
# sudo passwd shonan  ←  ユーザーに対するパスワードを設定します

次に、作成したLinuxユーザーに対して、Sambaへ登録します。pdbeditコマンドを使います。

# pdbedit -a shonan

ここで混乱してはいけないこととしては、Linuxユーザー作成時で登録したパスワードとは別に、Sambaファイルサーバー用のパスワードをさらに設定する必要があります。実際にWindowsからファイルサーバーへログオンするには、Linuxユーザーのパスワードではなくpdbeditコマンドで設定したパスワードであることを忘れないでください(私は簡単のためLinuxパスワードと同じにしていますが。。( ๑・∞・๑ ))

Sambaの設定

Sambaの設定を「/etc/samba/smb.conf」にて行います。

# vi /etc/samba/smb.conf
/etc/samba/smb.conf
# 追記または変更するもののみを記載します。他はデフォルト設定のままです
[global]
   workgroup = [所属するWindowsのワークグループ名]
   hosts allow = [接続許可するIPアドレスまたはネットワークセグメント]
[<任意のセクション名>]
   comment = [任意のコメント]
   path = [ファイルサーバーとして利用するディレクトリ]
   read only = no
   browsable = yes
   writable = yes

このファイルでは、Linuxファイルサーバー上のディレクトリを、任意のセクション名として区切ることで、柔軟な用途でファイルサーバーとして公開することができるのです。

そこで今回は「ファイルサーバー条件」の記載の通り、セクション名を「kazumi75kitty」という名前で、Linuxの「/mnt/miura/」というディレクトリを、ファイルサーバーとして利用できるようにしたいと思います。また、ネットワークが192.168.1.0/24にいることが前提ですから、このネットワークを許可します。

そうすると、/etc/samba/smb.confは、以下の設定にて行われる。

/etc/samba/smb.conf(例)
# 追記または変更するもののみを記載します。他はデフォルト設定のままです
[global]
   workgroup = [所属するWindowsのワークグループ名]
   hosts allow = 192.168.1. 127.0.0.1
   # hosts allowで、192.168.1.0/24と自分自身を許可する場合は、上記の記載方法になります。
[kazumi75kitty]
   comment = File Server Test in Miura Peninsula
   path = /mnt/miura
   read only = no
   browsable = yes
   writable = yes

所属するWindowsのワークグループ名は、コントロールパネルのシステムのプロパティで確認できるので、あえて記載しませんでした^^

ディレクトリに関してハマりやすいこと

セクションの「path」で指定したディレクトリは、所有者をpdbeditで登録したユーザーと同じにしないと、ファイルサーバーのファイルやディレクトリへアクセスできなかったりするので、所有者をちゃんと確認してから、変えてあげています

今回「/mnt/miura/」をファイルサーバーのスペースに使用し、例えばユーザーはshonanで使いたい場合は、/mnt/miura/のディレクトリの所有者がshonanである(rootではない)必要があります。

Ownerchange.png
上記画像のように(画像のユーザー名は運用中のものなので伏せています)

なお、ディストリビューションによってはsmb.confの説明の有無により、複雑だったり、シンプルだったりするので、画像で参考にしておきます(˶ ・ᴗ・ )⚐⚑

  • CentOS 8.1
    CentOS8-smbconf.png

  • openSUSE 15.1
    openSUSE15-smbconf.png

  • Ubuntu 20.04

    • globalセクション(非常に項目が多いので一部だけ)  Ubuntu20-smbconf-global.png
    • 自分で用意するセクション  Ubuntu20-smbconf-sect.png

パラメーターのチェック

# testparm /etc/samba/smb.conf

「Loaded services file OK.」と出れば、設定は正しく記載されているはず。

Sambaサービスの起動

CentOS8.1・openSUSE15.1
# systemctl start smb
# systemctl enable smb
# systemctl status smb
Ubuntu20.04
# systemctl start smbd
# systemctl enable smbd
# systemctl status smbd

enableを使うことで、再起動後も自動起動でファイルサーバーを使うことができます。

statusで「Active」「Running」と出ていて「Failed」が出ていないかを確認。もし「Failed」となっている場合は、smb.confの設定のスペルミスなど、再度確認に戻る羽目になります。

次に、ログを確認し、何もエラーがなければ、smb.confで指定したディレクトリを認識しています。

# less -r /var/log/samba/log.smbd

「canonicalize_connect_path failed for service samba, path /mnt/miura」のようにパス指定失敗が表示されるときは、指定したディレクトリが存在しているか、ls -lコマンドで所有者とパーミッションを確認し、アクセス可能でない可能性がある。

ファイルサーバーにアクセスしてみよう

では、Windowsのクライアントから、Linuxファイルサーバーにアクセスしてみます。
Windowsのエクスプローラーで「\\[LinuxファイルサーバーのIPアドレス]」を入力します。

まずはfirewalldの開放を行います(詳細は後術)。

# firewall-cmd --permanent --add-service=samba
# firewall-cmd --reload

ここでは、サーバーのIPアドレスが192.168.1.18なので「\\192.168.1.18\」でアクセスします。正常にサーバーを識別できれば、Windowsセキュリティの認証失敗ダイアログが出るはずです。
Conn-OK.png

接続できない場合は?

Conn-NG.png
最初の認証失敗の画面ではなく、接続できません、というメッセージが表示されている場合は、firewalld(後述)の設定で「firewall-cmd --list-all」で、Serviceに「samba」が許可されていなかったり、SambaサービスがLinuxで起動されているかを「systemctl status smb(d)」で確認すると「Failed」というような起動失敗が生じているかもしれません。

ログオンしてみよう

認証失敗ダイアログが表示され、ファイルサーバーに接続できたなら、pdbeditでSambaに登録したユーザーでログインします。ここでの例でのshonanの場合は、ユーザー名にshonanを、パスワードにpdbeditで登録した際のパスワード(もちろんLinuxユーザーのパスワードと区別します)を入力し、ログオンします。
Conn-logged-on.png
そうすると、ファイルスペース名として定義したもの、ここでの例では「kazumi75kitty」が表示されていれば、smb.confで作成したセクションによるファイルスペースが正常に認識されたことになります。

ファイルを置いてみよう

ファイルスペースが認識されたら、任意のファイルをいろいろと置いてみます。
FileSave-OK.png
また、置いたファイルもWindows上で編集し、保存できることも確認してみます。

ファイルが置けない、または読み取り専用となってしまう場合

Linuxサーバー側で、ファイルサーバーとして使用中のディレクトリで、所有者が違ってたり、パーミッションが読み書きできない状態になっているので、もう一度ls -lコマンドで再確認。

基本的なセキュリティ

Sambaの設定での基本セキュリティ

基本的には、部外者へのアクセスを許さない、ということが大前提です。応用なセキュリティとしては、ドメインやActive Directoryを用いる手法もありますが、ここでは割愛します。部外者のネットワークからはアクセスしないという前提で、自分の属するネットワークだけアクセスを許すという方法で、smb.confのhosts allowを制限します。

今回の例では、192.168.1.0/24でファイルサーバーを利用していますが、smb.confのhosts allowから192.168.1.を許可しない設定にしたらどうなるのでしょうか??

例えば、以下のように、192.168.1.を許可せず、192.168.2.を許可します。
hosts allow = 192.168.1. 127.0.0.1
hosts allow = 192.168.2. 127.0.0.1
Smb-allowdomainchg-1.png

それでエクスプローラーで「\\192.168.1.18\」へアクセスすると、以下のエラーがでるはずです。
Smb-allowdomainchg-2.png
そしてログ/var/log/samba/log.smbdは、以下のように、192.168.1.11からのアクセスが拒否されていることがわかります。
Smb-allowdomainchg-3.png

このようにして、Sambaを利用できるネットワークドメインを制限できましたね。

firewalldによる基本セキュリティ

先ほど「firewall-cmd」で、以下のファイアウォールを開放したと思います。

# firewall-cmd --permanent --add-service=samba
# firewall-cmd --reload

これは、firewalldというLinuxのファイアウォールで、Sambaというサービスを常に受信許可するという意味で、指定された以外のサービスは許可しないということを意味しています。どのサービスを許可しているかを確認する場合は、以下のコマンドを入力し「services: dhcpv6-client ssh samba」のように、services:以下に許可するサービスが表示されているかを確認します。

# firewall-cmd --list-all

なお、そのほかにrich rulesを用いて、Sambaの使用するポートを、特定のIPアドレスやネットワークを対象に許可するという手法も可能ですが、ここでは省略します。

参考文献

 1. CentOS7で作るネットワークサーバー構築ガイド【サーバ構築研究会 著】秀和システム
 2. 情報処理工学 –OSとインターネットの仕組み- 【木下 宏揚 著】コロナ社

※ 文献1.はCentOS 7 向けですが、SambaについてはCentOS 8 もyum→dnfにパッケージインストールコマンドが変わっただけの差なので、原形をとどめないような難しさは特にありません。
※ 文献2.の出版社名に「コロナ」がありますが、2020年6月現在、コロナウイルスの風評被害により「コロナ」とついただけで偏見するケースが見受けられます。コロナの本来の意味は、太陽の超高温の非常に薄いプラズマ大気であり、物理的にはコロナ放電の形状を意味するものですので、コロナの本来の意味を正しく使いましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

makeで "can not be used when making a PIE object" が出たら

とあるユーザープログラムを、Amazon Lightsail の Ubuntu 18.04 に載せ替えるべくMakefileからビルドしたら、リンカがエラーを吐いた。

現象

$ uname -a
Linux example 5.3.0-1023-aws #25~18.04.1-Ubuntu SMP Fri Jun 5 15:18:30 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ make
gcc -g -I../include -c foo.c
gcc -g -o foo foo.o bar.o -L ../lib -lwebsockets -lmysqlclient
/usr/bin/ld: bar.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object。 -fPIC を付けて再コンパイルしてください。
/usr/bin/ld: 最終リンクに失敗しました: 出力に対応するセクションがありません
collect2: error: ld returned 1 exit status
Makefile:14: recipe for target 'foo' failed
make: *** [foo] Error 1

調べてみるとgccのバージョン6からデフォルトで、PIE(Position Independent Executable=位置独立実行形式)としてリンクするように変わったらしい。
PIEとはPIC(Position Independent Code=位置独立コード)のオブジェクトファイルのみで構成された実行ファイルのこと。
なので、PICではないコードが混じっているとリンクに失敗するのだ。

確認

gccがビルドされたときのconfigureオプションをみてみる。

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 

--enable-default-pieがあるのが確認できる。
たしかにデフォルトでPIEが有効になっている。(PIEが動かないCPUアーキテクチャでは無効になっている)

一方、開発に使われていたマシンのconfigureにはそれが無く、gccのバージョンも5系とかなり古かった。

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)

対処

PIE形式にしなければ良いので、MakefileのLDFLAGS-no-pieを追加すれば良い。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む