【Raspberry Pi 3B】で自宅サーバー構築 Debianのインストール
めちゃくちゃ前(2019年)の話ですが、Raspberry Pi Model 3Bを買っていました:
今回から数回の記事にわたって、Raspberry Pi Model 3Bを使ってサーバー環境を構築しようと思っています。
最終形態としては以下の様なものを想定しています
- OSはDebian 10 buster ( Debian 10 (buster) リリースノート (32 ビット PC 用) )
- Docker-composeを使って複数のWebアプリ/サイトを一台のラズパイで制御する
- SSHで中身をいじることができる(認証は公開鍵を用いる)
この記事では、Raspberry PiにDebianをインストールして、ローカルの別PCからSSHして中身をいじるところまで行きます。
OS(Debian)を入れる
ダウンロード
下記リンクからOSのイメージデータをダウンロードします。
Tested images
この記事では、上記リンク先のリストでModel 3Bの動作確認が済んでいる最新版の「[xz-compressed image 376.97 MB, 2021-02-10 14:16:-0600」」をインストールしました。リンクをクリックすると自動的にダウンロードが始まります。
むかし(2018年くらい?)はここにIMGデータのリンクが書いてあったようですが、今は見当たりません。
OSをmicro SDに書き込む
RaspberryPiに使用するストレージ (micro SD) に、↑でダウンロードしたOSデータを書き込みます。それには、公式でリリースされているRaspberry Pi Imagerを用います。
↓のリンクからRaspberry pi imagerをインストールします。
https://www.raspberrypi.org/software/
起動すると、以下のような画面になるので、「Choose OS」を選択→「Use Custom」から、先ほどダウンロードしたOSファイル(hoge.img.xy)を選択します。
そして、「Choose Storage」ボタンから書き込むmicro SDカードを選択し、「Write」ボタンを押します
このような画面が出るので「YES」を押して書き込みを開始します。およそ5分くらいで終わりました。
OS動作確認
では、OSを入れたmicro SDカードをラズパイに差し込んで、電源を入れます。すると自動的に電源が入り、以下の様に「login : 」と表示されるので、「root」と入力しEnterを押して、root ユーザーでログインします(初期状態ではパスワードは必要ありませんでした)。
上の画像はログインしてDebianが起動した後の画面です。以下の様なコマンドを入力して、ハードウェアを確認します:
# cat /proc/cpu/info processor : 0 BogoMIPS : 38.40 features : fp asImd evtstrm crc32 cpuid .......(以下略。4コアCPUであることがわかります)
# cat /proc/meminfo MemTotal : 939552kB .......(以下略。1GBですね)
# ip address show ......ローカルIPアドレスなどが色々表示されます。 # ip a ......ローカルIPアドレスなどが色々表示されます。
# cat /etc/debian_info 10.8 # OSのバージョンを知ることができる。
ターミナルの文字がおかしい
キーボードの種類?によって?、一部の記号キーが正しく入力されないようです。物理キーボードのキー上に印刷されている文字とは異なる文字が入力されました。僕の場合は以下のキーを入力するために修正が必要でした
- 「:」を入力→Shift + 「れ (;)」
- 「\」を入力→「む(})」
色々なソフトをインストール
Debianが起動したので、色々なソフトウェアを入れていきます。
$ apt update
$ apt upgrade
$ apt install zsh tmux git ufw openssh-server openssh-clients network-manager wget neovim
$ apt-get install sudo zip unzip -y
- zsh : bashに代わるターミナル。Powerlevelkを使ってシンタックスハイライトをしたり色々できる
- tmuxx : ターミナル画面を分割する
- git : バージョン管理システム
- ufw : ファイアウォール
- network-manager : 名前の通りネットワーク管理を行う。`nmtui`コマンドを実行するとTUI(Text User Interface)を使ってWiFi接続などができるようになります:↓
- wget : wget [url]でネット上のファイルをダウンロードできます
- neovim : ターミナル上で動くエディター。vimよりイイゾ!!
- zip unzip : unzip [ファイル名] や zip [ファイル名] でZIPファイルを圧縮/解凍することだができる
Dockerのインストール
Dockerのインストールは公式ドキュメントを見ながらインストールしていきます
$ apt-get remove docker docker-engine docker.io containerd runc # 古いバージョンを削除 $ sudo apt-get update $ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release # レポジトリのセットアップ $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # Dockerの公式GPGキーを追加 $ echo "deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null $ sudo apt-get update;sudo apt-get install docker-ce docker-ce-cli containerd.io # Dockerをインストール
`docker --version` と入力してバージョンが出力されれば、インストールに成功しています
Docker-composeのインストール
これが大変だった、、、、、というかまだ解決していない、、、、。
https://github.com/docker/compose/releases を見ると、最近のバージョン(この記事を書いている時点では1.29.1が最新)ではx86_64のアーキテクチャ用のパッケージしか配布されていません。しかし。Raspberry pi 3B+ではアーキテクチャは、
$ uname -m
aarch64
です。なので、インストールには特別な方法が必要です(公式ドキュメントには書いていない)
このサイト等を見てgithubからクローンしてビルドしようとしたけれどうまくいかなかった、、、。そこでpipを使ってインストールすることにした。
$ sudo apt update $ sudo apt install -y python python-pip libffi-dev python-backports.ssl-match-hostname $ sudo pip install docker-compose $ sudo apt-get -y install python3-pip $ pip3 install docker-compose
上記のようにするとdocker-composeをインスト―ルはできます。できるんですが、正常に動いてくれません、、、、
docker-compose up -dと打ってもコンテナが動きません(Docker単体だと動くのですが、composeを使うと無理みたい)
おそらく↓と同じような現象なのですが、まだ解決していない状態です、、、
github.com
他にもいくつかの方法があったのですが、上手くいっていません。
タイムゾーン設定
$ apt-get install locales $ sudo dpkg-reconfigure locales
を実行すると以下の様な画面が表示されます。
「ja_JP.UTF-8」までスクロールしてスペースキーを押すと選択できます(選択されると行頭のかっこが[ * ]になる(↑写真))。選択後、エンターを押すと次は以下の画面になる:
「ja_JP.UTF-8」を選択(上画像の様に赤くなっていればOK)してエンターを押します
次に、以下のコマンドを実行します
sudo dpkg-reconfigure tzdata
「アジア」を選択→「東京」を選択します。
これでタイムゾーンの設定が終わりました。dateコマンドで正しい時刻が表示されればOKです。
$ date 2021年 4月 24日 土曜日 16:54:48 JST
日本語ツールのインストール
上記のタイムゾーン設定を行ったのち、以下のコマンドを実行すると日本語ツールがインストールされます。
$ sudo apt install man
terminalの出力文字が日本語になるはずです。
Powerlevel10kの設定
これをするとターミナルの見た目がカラフルできれいになります。
以下のコマンドを実行します
$ cd ~/適当なフォルダ # まずはフォントファイル(ttf)をダウンロード $ sudo wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttfwget $ sudo wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf $ sudo wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf $ sudo wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf # フォントをインストール(参考:https://gist.github.com/matthewhartman/7b1661dbe6ff26a231e4) # 必要なら文頭にsudo付けてね $ apt-get install xfonts-utils x11-xserver-utils -y $ apt install fontconfig $ mv *.ttf /usr/share/fonts/truetype # (フォルダが無ければmkdirも!) $ cd /usr/share/fonts/truetype $ mkfontscale $ mkfontdir $ fc-cache $ xset fp rehash
ユーザーの追加
初期ではrootユーザーしかいないので、SSHする用のユーザーを追加します。以下のサンプルではadmin01という名前のユーザーを作成していますが、admin○○みたいな名前だと総当たり攻撃に弱くなる気もします、、、
$ adduser admin01 $ gpasswd -a admin01 sudo # 管理者権限付与 $ usermod -aG sudo admin01 # 上と同じ意味。上で実行できればそれでよし?
admin01に管理者権限が付与されているかどうかは、admin01でsudo関連のコマンドが実行できればOKです
$ su admin01 #admin01ユーザーに切り替え
SSHの設定
以下の様な設定にしたいと思います
- SSHのポートを22から任意番号に変更する(↓のサンプルでは10022)
- rootのログインは不可
- パスワード入力でのログインは不可、公開鍵認証のみ
- ただし、最初は鍵をSCPで転送するので、最初だけパスワードでログインOKにして置き、鍵をラズパイに転送したのちに、パスワード不可に設定する
- ufwでファイアウォールを設定
- 特定のポートのみアクセス許可
ではまず、SSHを止めます
$ systemctl stop ssh # sshを止める $ systemctl status ssh
次に、/etc/ssh/sshd_configを以下の様に編集し、セキュリティを強化します。(システム設定ファイルを編集するのでバックアップを取っておくと良いと思います)
# sshd_config Port 10022 # 好きな番号で(デフォルトでは22になっている) PermitRootLogin no # rootユーザーのログインを許可しない ChallengeResponseAuthentication no # 恐らくこれはそのまま UsePam yes # おそらくこれもそのまま # 以下はなくても良いがエラーが出たら試してみるのはありかも? # AllowUsers admin01 (その他の部分は変更せずに、そのまま保存)
その他のセキュリティの設定については↓を見てください
ufwでファイアウォールの設定をします。今もう一度調べてみるとiptablesを使うのが主流みたいですね。
$ ufw allow ssh $ ufw default deny #明示的に設定していないポートはアクセス不可 $ ufw allow 10022 # sshd_configで設定したSSHのポートをオープンにする $ ufw enable # ファイアウォールを有効にする
そして、SSHを起動します。
$ systemctl restart ssh $ systemctl status ssh (以下の様に表示されればOKです) ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2021-04-24 05:48:36 UTC; 35min ago Docs: man:sshd(8) man:sshd_config(5) (以下略)
そして、ラズパイのIPアドレスを確認し↓
$ ip a (略) 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether b8:27:eb:31:ee:ed brd ff:ff:ff:ff:ff:ff inet 192.168.43.118/24 brd 192.168.43.255 scope global dynamic noprefixroute wlan0 (略)
↑の場合だと192.168.43.118ですね。そして、同じローカルネットワークの別PCからSSHしてみます
$ ssh admin01@192.168.43.118 -p 1002 Are you sure you want to continue connecting (yes/no)? yes admin01@192.168.43.118's password: パスワードを入力(表示されませんが入力できています) admin01@rpi3-20210209:~$ echo hello hello
admin01でログイン成功しました!!!
公開鍵認証にする
まず、クライアント側のPCで`ssh-keygen`を実行し、鍵のペアを作成します。
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/owner4/.ssh/id_rsa): id_rsa ←鍵の保存先(何も入力しないと括弧内に保存される) Enter passphrase (empty for no passphrase): <-- パスフレーズ入力(任意) Enter same passphrase again: SHA256:114514hogehoge@aaaaa
↑の様に保存先に`id_rsa`コマンドと入力した場合、現在いる場所に id_rsa(秘密鍵)とid_rsa.pub(公開鍵)が作成されます。
そして、クライアントPCで以下のコマンドを実行することでサーバーに公開鍵を転送することができます
$ ssh-copy-id -i ./id_rsa.pub admin01@192.168.43.118 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "./id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys admin01@192.168.43.118's password: ←パスワード入力 Number of key(s) added: 1 Now try logging into the machine, with: "ssh -p '10022' 'admin01@192.168.43.118'" and check to make sure that only the key(s) you wanted were added.
これで公開鍵の転送ができました!!!
試しに公開鍵を使ってSSHしてみます!
$ ssh admin01@192.168.43.118 -p 1002 -i ./id_rsa Linux rpi3-20210209 4.19.0-14-arm64 #1 SMP Debian 4.19.171-2 (2021-01-30) aarch64 (略) Last login: Sat Apr 24 05:49:23 2021 from 192.168.43.240 admin01@rpi3-20210209:~$
できたぁ!!!
パスワード認証の無効化
ということで、もうパスワード認証は使わないので無効化します。
/etc/ssh/sshd_configを以下の様に設定します
PasswordAuthentication no # パスワード認証を無効化 ChallengeResponseAuthentication no # チャレンジ(レスポンス)認証を無効化
SSHを再起動します
$ systemctl restart ssh
これで、別PCからパスワードログインをしようとして、以下の様に拒否されればOKです。
$ ssh admin01@192.168.43.118 -p 10022 admin01@192.168.43.118: Permission denied (publickey). zsh: exit 255 ssh admin01@192.168.43.118 -p 10022
ということで、Raspberry Piでサーバーをたてて、LAN中の他のコンピュータから公開鍵認証でSSHすることに成功しましたとさ。めでたしめでたし!!
【お知らせ】 New Video!
AviUtlで個人的に動画編集を行ってきましたが、その完成作品の一部を紹介します~~。編集全部僕のやつと他の人との共同製作」のものがあります。
Adobe製品ほしい~~、けど高い~~。
久しぶりにまじめに動画編集しました。
みてください!!!!
編集中のスクショ:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
www.youtube.com
同じく編集を担当しました。
今日は生徒会オリエンテーションがありましたねー
— 小倉高校Public Address係 (@PA__kokura) 2019年4月12日
昨日は学校開放説明会でボツになったの公開したんで、今回は本番で流したのを公開しときますね pic.twitter.com/ySxHuwcsWf
撮影と編集を担当しています。今見返すと色々改良の余地があります。特にフォント。なぜ全てUIゴジックなのか...
【特報】これからもよろしくですhttps://t.co/bUVXIiovG7 pic.twitter.com/7Gspuqi2Kg
— Nishi-P (@20niship) 2020年6月12日
2020/06/12に、このブログの合計PV数が500,000件を超えました!!!本当にありがとうございます!!!拙い内容ですが、これからもよろしくお願いしますm(__)m
音ハメ練習 (AviUtl only) pic.twitter.com/fNXGRxklQl
— Nishi-P (@20niship) 2020年6月2日
FireFly(自称VJソフト)を作った時のPV
分かる人にはわかると思いますが、物語シリーズのテロップをパクっています
— Nishi-P (@20niship) 2020年3月6日
高校の文化祭で映画「君の名は」のパロディCMを作った時のやつです。ほかのシーンは人が映っているのでカットで。
昔の素材(一昨年の文化祭)見つけた。#blender pic.twitter.com/VUqZQQ3FpA
— Nishi-P (@20niship) 2019年11月4日
高校の文化祭で「アタゴジラ」を作った時のCGのメイキング画像です。Blenderを使っています
文化祭まであと2日。
— 小倉高校科学部 (@kagaku_kokura) 2018年5月23日
是非科学部にお越し下さい。 pic.twitter.com/gfjbCOiFYA
高校の科学部の部活動紹介CM
【Ubuntu】MongoDBをインストール + Node.jsでDB操作
MongoDBはNoSQLと呼ばれるデータベースの一種です。
RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理します。
インストール
公式ドキュメント(下リンク)に書かれている通りに実行します。
Install MongoDB Community Edition on Ubuntu — MongoDB Manual
$ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - $ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list $ sudo apt-get update $ sudo apt-get install -y mongodb-org
これでインストールは完了です。
mongoDBを起動させるには、以下のどちらかのコマンドを実行します。
# 以下のどちらか一方を実行 $ sudo service mongod start $ sudo systemctl start mongod
サンプルプログラム
mongoDBにアクセスしusersコレクションを編集するNode.jsのプログラムです。
function sleep(ms) { return new Promise(resolve => { setTimeout(resolve, timeout=ms); }) } console.log ("*** 開始 ***") const MongoClient = require('mongodb').MongoClient; const assert = require('assert'); const dbName = 'myproject'; const client = new MongoClient('mongodb://localhost:27017'); //サーバーに接続する client.connect(function(err) { assert.strictEqual(null, err); console.log("Connected successfully to server"); const db = client.db(dbName); // usersコレクションを作成し、そこにアクセスする。 const users = db.collection('users'); users.deleteMany({}); //usersのすべてのデータを削除 // ==================== // データ追加 // ==================== // userを追加 users.insertOne({name: 'name1', age:1, sex:"male"}); users.insertOne({name: 'name2', age:2, sex:"male"}); users.insertOne({name: 'name3', age:3, sex:"male"}); users.insertOne({name: 'name4', age:4, sex:"female"}); users.insertOne({name: 'name5', age:5, sex:"female"}); users.insertOne({name: 'name6', age:6, sex:"female"}); // このように配列を引数に取ることで、複数同時に追加することもできる users.insertMany([ {name: 'test1', id:'id7', age:7, sex:"female"}, {name: 'test2', id:'id8', age:8, sex:"male"} ]); // ==================== // 検索 // ==================== // 男性を出力するプログラム users.find({sex:"male"}).each(function(err, doc) { if(doc !== null){ console.log(doc.name); } }); // 全データ出力 // users.find().each(function(err, doc) { // console.log(doc); // }); // 出力を制御する(↓のプログラムの場合は_idを出力せず、nameを出力する) users.find({}, { projection: {_id: 0, name: 1 } }).toArray(function(err, result) { if (err) throw err; console.log(result); }); // ==================== // データ削除 (Node.jsが非同期処理なので、async-awaitで書かないと、その下のcount()までに削除処理が間に合わない可能性がある。) // ==================== users.deleteOne({"age":0});//ageが0のデータを一つ削除 users.deleteMany({"age":{"$lte": 4}}) //ageが4以下のデータを削除 users.deleteMany({}) // 全データ削除 // ==================== // データ個数を調べる // ==================== users.count({}).then((result) => { // find(条件).count()という書き方もある console.log("最終的なデータの数 = " + String(result)); }) client.close(); console.log ("*** 終了 ***") });
実行
上のプログラムを実行するには以下のコマンドを実行して下さい。
$ npm instal mongodb $ npm index.js # ↑のJavaScriptファイル名
以下のように出力されるはずです。
*** 開始 *** *** 終了 *** name1 name2 name3 test2 [ { name: 'name1' }, { name: 'name2' }, { name: 'name3' }, { name: 'name5' }, { name: 'name4' }, { name: 'test1' }, { name: 'test2' }, { name: 'name6' } ] 最終的なデータの数 = 8
SocketExeptionで繋がらなくなった
Ubuntuのシステムをアップデートしたら、mongoコマンドを実行しても以下のようなエラーが出てデータベースにつながらなくなりました。
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb 2020-10-23T16:57:38.500+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused : connect@src/mongo/shell/mongo.js:353:17 @(connect):2:6 2020-10-23T16:57:38.501+0000 F - [main] exception: connect failed 2020-10-23T16:57:38.501+0000 E - [main] exiting with code 1
調べていくと↓の記事に出会い、無事解決しました。ありがたい〜〜
qiita.com
解説
気が向いたら書く......
//TODO