本当はサーバーを構築したらすぐに設定するべき項目その2。

ラズパイの記事って結構あるわけで、ということはラズパイ持っている人も少なからずいるわけで、そんでもってそれを狙う輩もいるわけで。

そんな中、知れ渡っているデフォルトのユーザーや、パスワードも変更していない状態ってやっぱり嫌だよね。

まぁ、ラズパイを外に出しているわけでもないので、狙われるわけないだろ?なんてことは思っちゃっているんだけれども、「大丈夫だろう」ではなく「大丈夫じゃないかもしれない」というリスクのあるほうに考え方をシフトしなきゃイカン、と思い至った。

レッツ、ネガティブシンキング!

1.rootユーザーのパスワード設定

現状rootユーザーにパスワードが設定設定されていないことによりsuも出来ないしsshも出来ないなら良いんじゃね?と思う。

そもそもrootユーザーにパスワードを設定するということはセキュリティリスクを高める行為、そういう認識です。

ただし、今後のサーバー回復作業でどのユーザーも使用できなくなった場合の最後の砦として設定しておきます。

pi@raspberrypi:~ $ sudo passwd root
新しいパスワード:
新しいパスワードを再入力してください:
passwd: パスワードは正しく更新されました

2.piユーザーに代わる新たなユーザーの追加とpiの削除

2.1.新ユーザーの追加

知れ渡っているpiユーザーを削除するために、代わりとなる新しいユーザーを追加します。

pi@raspberrypi:~ $ sudo adduser [新ユーザー名]

ユーザ `[新ユーザー名]' を追加しています...
新しいグループ `[新ユーザー名]' (1001) を追加しています...
新しいユーザ `[新ユーザー名]' (1001) をグループ `[新ユーザー名]' として追加してい ます...
ホームディレクトリ `/home/[新ユーザー名]' を作成しています...
`/etc/skel' からファイルをコピーしています...
新しいパスワード:
新しいパスワードを再入力してください:
passwd: パスワードは正しく更新されました
[新ユーザー名] のユーザ情報を変更中
新しい値を入力してください。標準設定値を使うならリターンを押してください
        フルネーム []:
        部屋番号 []:
        職場電話番号 []:
        自宅電話番号 []:
        その他 []:
以上で正しいですか? [Y/n] Y

途中の「フルネーム」以降は何も入力せずリターンだけ。

あと気付いたけど、日本語対応の仕方が悪いのか「`」と「’」が混じってるねw

2.2.「pi」ユーザーから新ユーザに権限をコピー

まずはpiユーザーが所属しているgroupを確認。

pi@raspberrypi:~ $ groups pi

pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio

次に、[新ユーザー名]をpiユーザーと同じgroupに所属させてあげる。

pi@raspberrypi:~ $ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio [新ユーザー名]

追加が出来たら、exitして一度ラズパイからログアウトして、追加したユーザーでログインできるか確認します。

ログインしたら/home/piにあるpiユーザーのファイルを/home/[新ユーザー名]にすべてコピーしておきます。

[新ユーザー名]@raspberrypi:~ $ sudo cp -r /home/pi/* /home/[新ユーザー名]/.

あなたはシステム管理者から通常の講習を受けたはずです。
これは通常、以下の3点に要約されます:

    #1) 他人のプライバシーを尊重すること。
    #2) タイプする前に考えること。
    #3) 大いなる力には大いなる責任が伴うこと。

[sudo] [新ユーザー名] のパスワード:

なんか、今まで見たことないメッセ出て少しビビるが気にせずにパスワード入れてコピーする。

2.3.新ユーザーの、パスワード無しsudo実行設定

さっきもメッセージ出たけれど、新ユーザーではsudoするとパスワードを聞かれます。

これを抑止してパスワード無しでsudo出来るようにします。

[新ユーザー名]@raspberrypi:~ $ sudo visudo

:
#includedir /etc/sudoers.d
[新ユーザー名] ALL=(ALL) NOPASSWD: ALL

visudoの操作がviという割にviじゃなくてアレだけど、ファイルの最後の上記1行を加えてCtrl+xであとは指示通りにすれば更新される。:wqじゃねぇの、なんなのー?

あと、piユーザーをsudoers(管理者のグループ)から除外しておく。

[新ユーザー名]@raspberrypi:~ $ sudo gpasswd -d pi sudo

ユーザ pi をグループ sudo から削除

2.4.piユーザーの、自動ログイン無効化

ラズパイ初期状態は電源投入時piユーザーで自動ログインとなるのを解除します。

[新ユーザー名]@raspberrypi:~ $ sudo raspi-config

とすると以下のような画面に。

3 Boot Options -> B1 Desktop/CLI -> B1 Consoleと選択。

これで自動ログインとはならず、ユーザーパスワードを聞かれるようになるのかな?

最後はFinishを選択すればrebootされます。

2.5.piユーザーの削除

以下のコマンドでpiユーザーを削除。

[新ユーザー名]@raspberrypi:~ $ sudo userdel -r pi

userdel: グループ pi には他のメンバーがいるので削除しませんでした
userdel: pi のメールスプール (/var/mail/pi) がありません

あれ?削除できなかったかな?と思って以下のコマンドで確認。

[新ユーザー名]@raspberrypi:~ $ id -a pi

id: `pi': no such user

というわけで無事削除されているっぽい。試しに/homeの下覗いてみたけどpiフォルダがちゃんと削除されていました。

2.6.Sambaの設定変更

たしかSambaの設定で共有フォルダのユーザーをpiとしていたため、Windows10からフォルダが見れなくなりました。

なので修正。

[新ユーザー名]@raspberrypi:/home $ sudo vi /etc/samba/smb.conf

[raspi4]
path = /data
public = Yes
read only = No
browsable = Yes
guest ok = Yes
force user = [新ユーザー名]

修正したらsambaデーモンを再起動。

[新ユーザー名]@raspberrypi:/home $ sudo systemctl restart smbd

これで共有フォルダ復活です。

3.SSHの設定見直し

3.1.SSHのポート番号変更

デフォルトの22から別の番号に変更する。49152~65535の間で好きな番号。

変更する前に現在開いているポートを確認。

確認するコマンドはssまたはnetstat。どうも最近はss推しらしい。

オプションは以下。

オプション 意味
-A 接続状態を表示するアドレスファミリを指定する
-I 指定したNICの情報のみ表示する(ex. -Ieth0)
-a 全てのアクティブなソケットを表示する
-c 1秒ごとに更新しつつ表示する
-e 詳細情報を表示する
-g IPv4とIPv6のマルチキャストグループメンバーシップ情報を表示する
-i 全てのNICの状態テーブルを表示する
-l 接続待ち(LISTEN)状態にあるソケットのみ表示する
-n ホストやユーザーの名前解決を行わず数字のまま出力する
-o ネットワーキングタイマーの情報を出力する
-p ソケットが属すプログラムのPIDとプロセス名を表示する
-r ルーティングテーブルを表示する
-s 各プロトコルの統計情報を表示する
-t TCPソケットを表示する
-u UDPソケットを表示する
-v 詳細な情報を表示する
-4 IPv4のみ
-6 IPv6のみ

さて現在Windows10からラズパイにSSH接続しているのでtcpに絞って接続確立しているポートを表示してみる。

[新ユーザー名]@raspberrypi:/home $ ss -t

State    Recv-Q    Send-Q       Local Address:Port        Peer Address:Port
ESTAB    0         36            192.168.0.11:ssh        192.168.0.101:60074

名前解決せずに番号で表示してみる。

[新ユーザー名]@raspberrypi:/home $ ss -tn

State    Recv-Q    Send-Q       Local Address:Port        Peer Address:Port
ESTAB    0         36            192.168.0.11:22         192.168.0.101:60074

はい、sshが22番で接続していることがわかりました。そんじゃ変更。

[新ユーザー名]@raspberrypi:/home $ sudo vi /etc/ssh/sshd_config

:
#Port 22
Port [新ポート番号]

そしたらsshdデーモンを再起動。

[新ユーザー名]@raspberrypi:/home $ sudo systemctl restart sshd

一度ログアウトして再度Windows10からTeraTermで新ポート番号指定して接続。

確認してみる。

[新ユーザー名]@raspberrypi:~ $ ss -tn

State    Recv-Q    Send-Q       Local Address:Port          Peer Address:Port
ESTAB    0         96            192.168.0.11:[新ポート番号] 192.168.0.101:62959

[新ユーザー名]@raspberrypi:~ $ ss -tln4

State    Recv-Q    Send-Q       Local Address:Port          Peer Address:Port
:
LISTEN   0         128                0.0.0.0:[新ポート番号]             0.0.0.0:*

ちゃんと[新ポート番号]で接続確立出来ているし、[新ポート番号]で接続待ち(LISTEN)しています。

3.2.パスワード認証から公開鍵認証への変更

正直、これが今回一番面倒。というか、あまりやった事がないのでドキドキする。

Windows10側のコマンドプロンプト上で鍵を作成する。

$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/[Windows10上のusername]/.ssh/id_rsa):
Created directory '/c/Users/[Windows10上のusername]/.ssh'.
Enter passphrase (empty for no passphrase):  # ←パスフレーズを入力
Enter same passphrase again:  # ←パスフレーズを再度入力
:

これで/c/Users/[Windows10上のusername]/.sshの下に秘密鍵id_rsaと公開鍵id_rsa.pubが出来ました。

次はラズパイ上。

ホームディレクトリの下に.sshディレクトリを作成する。

[新ユーザー名]@raspberrypi:~ $ mkdir .ssh

今度はWindows10から。公開鍵をラズパイに転送する。転送にはscpを使用。

$ scp -P [新ポート番号] /c/Users/[Windows10上のusername]/.ssh/id_rsa.pub [新ユーザー名]@192.168.0.11:/home/[新ユーザー名]/.ssh                            

The authenticity of host '[192.168.0.11]:[新ポート番号] ([192.168.0.11]:[新ポート番号])' can't be established.
ECDSA key fingerprint is SHA256:OOoooOOOOooOOOOoOOOOOOOOOOooooOOoOOOOOOOOOO.                                                 
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes   # ←yesを入力
Warning: Permanently added '[192.168.0.11]:[新ポート番号]' (ECDSA) to the list of known hosts.
[新ユーザー名]@192.168.0.11's password:   # ←ラズパイ上の[新ユーザー名]に対するパスワードを入力
id_rsa.pub                                100%  570    96.3KB/s   00:00

今度はラズパイ上で。

初めて公開鍵を設定するので

  1. 公開鍵(authorized_keys)のパーミッションは600にして
  2. .sshフォルダのパーミッションは700にして
  3. id_rsa.pubをauthorized_keysに結合したら、id_rsa.pubを消す

ってことを実施する。

[新ユーザー名]@raspberrypi:~ $ cd ~
[新ユーザー名]@raspberrypi:~ $ chmod 700 .ssh/
[新ユーザー名]@raspberrypi:~ $ cat .ssh/id_rsa.pub >> .ssh/authorized_keys
[新ユーザー名]@raspberrypi:~ $ chmod 600 .ssh/authorized_keys
[新ユーザー名]@raspberrypi:~ $ rm .ssh/id_rsa.pub

これで鍵認証出来るはずなので、Windows10からTeraTermで接続確認。

これで接続出来ればOK。というか、ここで接続確認出来ない場合はこの先を実行しちゃダメ。

3.3.パスワード認証の禁止設定

鍵認証のみを有効にしてパスワード認証を禁止します。

[新ユーザー名]@raspberrypi:~ $ sudo vi /etc/ssh/sshd_config

:
#PasswordAuthentication yes
PasswordAuthentication no
:

3.4.rootユーザーでのログイン禁止設定

更に、rootユーザーでのログインを禁止します。

[新ユーザー名]@raspberrypi:~ $ sudo vi /etc/ssh/sshd_config

:
#PermitRootLogin prohibit-password
PermitRootLogin no
:

そしたらsshdデーモンを再起動。

[新ユーザー名]@raspberrypi:~ $ sudo systemctl restart sshd

これで秘密鍵は絶対に失くせなくなった。失くしたらラズパイに接続出来ん!

3.5.【おまけ】TeraTermで自動ログイン

自分は(例えば)raspberrypi.ttlというファイルに以下を書いて、それをダブルクリックするだけでTeraTermが起動してラズパイに接続できるようにしています。

username = '[新ユーザー名]';
hostname = '[ラズパイのIPアドレス]';
password = '[ssh-keygenした時のパスフレーズ]';
inifile = '[TeraTermの外観を保存したiniファイルの絶対パス]\raspberrypi.ini'
keyfile = 'C:\Users\[Windows10上のusername]\.ssh\id_rsa'

msg = hostname
strconcat msg ':[新ポート番号] /ssh /auth=publickey /user='
strconcat msg username
strconcat msg ' /passwd='
strconcat msg password
strconcat msg ' /keyfile='
strconcat msg keyfile
strconcat msg ' /F='
strconcat msg inifile


connect msg

4.ファイアウォールの設定

ラズパイのファイアウォールとしてufwを使用します。

iptablesっていうのもあって、これはCentOS6の時に使用していたので知っているんだけど設定ファイルへの書き方がよく分からなくて悩んだ覚えあり。

それに比べてufwは簡単そう。

あとちなみにCentOS7以降のファイアウォールはfirewalldになって、設定ファイルに書くっていうよりコマンドにより設定できるようになって少し取っつき易くなってます。

4.1.ファイアウォールの役割

意味分かんないで実行するより意味分かって実行するほうが、なんぼか良い気がする。

で、役割としては

  1. フィルタリング機能でアクセスを識別、制御
  2. アドレス変換機能でIPアドレスを設定
  3. 監視機能でログと追跡

つ~わけで、ファイアウォールって大体外側と内側の中間にいて、今回は上記の1を期待して導入します。

外部からのアクセスを制御し、不正アクセスを遮断する。

う~ん、ラズパイを外部に出していないので果たして必要なのかは疑問だけど、それでも万が一外部に晒された状態になった時、その時に備えあれば憂い無し。という理解で良いのか。良いのだ。

4.2.ufwのインストール

以下のコマンドでインストールする。

[新ユーザー名]@raspberrypi:~ $ sudo apt-get install ufw

4.3.ufwの設定

とりあえず、SSHで使用しているポート番号と(以前記事にした)GitBucketで使用しているポート番号8081を開放して、その他のポートを閉じてみる。

[新ユーザー名]@raspberrypi:~ $ sudo ufw allow [SSHの新ポート番号]
Rules updated
Rules updated (v6)
[新ユーザー名]@raspberrypi:~ $ sudo ufw allow 8081
Rules updated
Rules updated (v6)
[新ユーザー名]@raspberrypi:~ $ sudo ufw default deny
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

このままだとufwはまだ有効化されていないので、以下のコマンドで有効化する。

[新ユーザー名]@raspberrypi:~ $ sudo ufw enable

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

sshすなわちWindows10からTeraTermでラズパイに繋いて操作していると、なんか上記のメッセ出るらしいけど気にせずにyとしておく。

そんでもって設定を確認。

[新ユーザー名]@raspberrypi:~ $ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] [SSHの新ポート番号]         ALLOW IN    Anywhere
[ 2] 8081                       ALLOW IN    Anywhere
[ 3] [SSHの新ポート番号] (v6)    ALLOW IN    Anywhere (v6)
[ 4] 8081 (v6)                  ALLOW IN    Anywhere (v6)

上記コマンドのオプションnumberedはルール番号の表示指定です。

というのも、ついでにGitBucket使用の8081を別のポート番号に変更して動かしたくて、ルール番号を指定して今指定したばかりの8081を削除したいから。

削除するべきは2と4です。と思ったら2を消した後は4が3に繰り上がりますwうほww。

[新ユーザー名]@raspberrypi:~ $ sudo ufw delete 2

Deleting:
 allow 8081
Proceed with operation (y|n)? y
Rule deleted

[新ユーザー名]@raspberrypi:~ $ sudo ufw delete 4

ERROR: Could not find rule '4'

[新ユーザー名]@raspberrypi:~ $ sudo ufw status numbered

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] [SSHの新ポート番号]         ALLOW IN    Anywhere
[ 2] [SSHの新ポート番号] (v6)    ALLOW IN    Anywhere (v6)
[ 3] 8081 (v6)                  ALLOW IN    Anywhere (v6)

[新ユーザー名]@raspberrypi:~ $ sudo ufw delete 3

Deleting:
 allow 8081
Proceed with operation (y|n)? y
Rule deleted (v6)

[新ユーザー名]@raspberrypi:~ $ sudo ufw status numbered

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] [SSHの新ポート番号]         ALLOW IN    Anywhere
[ 2] [SSHの新ポート番号] (v6)    ALLOW IN    Anywhere (v6)

というわけで、SSHのポート番号のみが許可された状態になりました。

次にGitBucketの新ポート番号を許可していきます。

[新ユーザー名]@raspberrypi:~ $ sudo ufw allow [GitBucketの新ポート番号]

Rule added
Rule added (v6)

[新ユーザー名]@raspberrypi:~ $ sudo ufw status numbered
Status: active

     To                             Action      From
     --                             ------      ----
[ 1] [SSHの新ポート番号]             ALLOW IN    Anywhere
[ 2] [GitBucketの新ポート番号]       ALLOW IN    Anywhere
[ 3] [SSHの新ポート番号] (v6)        ALLOW IN    Anywhere (v6)
[ 4] [GitBucketの新ポート番号] (v6)  ALLOW IN    Anywhere (v6)

あとは/etc/rc.localに書いてあるGitBucketの自動起動時に指定しているポート番号を新ポート番号に変更してrebootするだけ。

・・・reboot、怖ぇなw

[新ユーザー名]@raspberrypi:~ $ sudo vi /etc/rc.local

:
java -jar /opt/gitbucket/gitbucket.war --gitbucket.home=/data/gitbucket/ --port=[GitBucketの新ポート番号] &
:

[新ユーザー名]@raspberrypi:~ $ sudo reboot now

ちなみにufwを停止したい場合は以下のコマンドを実行する。

[新ユーザー名]@raspberrypi:~ $ sudo ufw disable

と、ここでSambaの使用ポート番号を開放し忘れwwwWindows10のエクスプローラーからアクセスできんwwww

ufwはアプリを指定して開放することも可能。で、アプリリストの表示は以下。

[新ユーザー名]@raspberrypi:~ $ sudo ufw app list
Available applications:
  AIM
  Bonjour
  CIFS
  DNS
  Deluge
  IMAP
  IMAPS
  IPP
  KTorrent
  Kerberos Admin
  Kerberos Full
  Kerberos KDC
  Kerberos Password
  LDAP
  LDAPS
  LPD
  MSN
  MSN SSL
  Mail submission
  NFS
  OpenSSH
  POP3
  POP3S
  PeopleNearby
  SMTP
  SSH
  Samba
  Socks
  Telnet
  Transmission
  Transparent Proxy
  VNC
  WWW
  WWW Cache
  WWW Full
  WWW Secure
  XMPP
  Yahoo
  qBittorrent
  svnserve

というわけで、Sambaを指定して開放してみる。・・・Yahooってなんだ?www

[新ユーザー名]@raspberrypi:~ $ sudo ufw allow Samba

Rule added
Rule added (v6)

[新ユーザー名]@raspberrypi:~ $ sudo ufw status numbered

Status: active

 To                                  Action      From
 --                                  ------      ----
 [ 1] [SSHの新ポート番号]             ALLOW IN    Anywhere
 [ 2] [GitBucketの新ポート番号]       ALLOW IN    Anywhere
 [ 3] Samba                          ALLOW IN    Anywhere
 [ 4] [SSHの新ポート番号] (v6)        ALLOW IN    Anywhere (v6)
 [ 5] [GitBucketの新ポート番号] (v6)  ALLOW IN    Anywhere (v6)
 [ 6] Samba (v6)                     ALLOW IN    Anywhere (v6)

ポート番号が表示されるんじゃなくてSambaって表示されるのか、へ~。

でもこれで無事にラズパイの共有フォルダに再びアクセスすることができました。

まとめ

少し調子に乗って長く書き過ぎた。

参考文献

初心者向!Raspberry Pi 最低限のセキュリティ設定【所要時間 30分】 - Qiita

買ったらまず実施!RaspberryPiのセキュリティ対策 - Qiita

ラズパイでやらなければいけない4つのセキュリティ対策! - Qiita

Make: Japan | Raspberry Piを攻撃から守るための手順

あなたのラズパイは穴だらけ? ユーザーが検討すべき脅威への対策 (1/2) - MONOist(モノイスト)

ラズパイ入手したらまずやること、デフォルトユーザーとSSHログイン認証を変更する (1/3) - MONOist(モノイスト)

「ラズパイの穴」を埋めるために、不要サービスの確認とOS自動更新を実装する (1/2) - MONOist(モノイスト)

Raspbianにファイアウォールufwのインストールと設定