m6uのエンジニアっぽい日記

PHP利用開発やFuelPHP利用開発、PostgreSQL利用開発、Androidアプリ開発、CentOS7サーバー構築など、テクニカルでエンジニアっぽい内容の日記

CentOS7でSSH必須にしたあとに、個別ユーザーを絞ってパスワード認証を復活させる方法

背景

CentOS7サーバーを立てていて、古いシステムを移植しているのですが、FTP接続するのにSCP/SFTPでなくFTPを使わざるを得ない状況になり、急遽やり方を調べてみました。
なお、この記事については、teratailでの質問:「CentOS - CentOS7&Vsftpdで非SSHユーザーをFTPできるようにしたい(96994)」を再構成したものです。

SSH側とvsftpd側の両方で穴を開ける

なお、前提として、追加したユーザー名「foobarbaz」をグループ「web」に所属させています。

SSH(6.6.1p1-35.el7_3)側

定義ファイル「/etc/ssh/sshd_config」を点検して、ファイル末尾に「Match User foobarbaz」行を追加して、「PasswordAuthentication yes」を加えました。  こんな感じです↓

Match User foobarbaz
  PasswordAuthentication yes

vsftpd(3.0.2-21.el7)側

ユーザー定義用ファイルを置くディレクトリ「userconf」を「/etc/vsftpd」の下に作り:
「# mkdir /etc/vsftpd/userconf」
vsftpdの定義ファイル「/etc/vsftpd/vsftpd.conf」に下記の行を追加し
「user_config_dir=/etc/vsftpd/userconf」
そのディレクトリにfoobarbazというユーザー名そのもののファイル名で定義を
「local_root=/var/www/html/path/to/target/directory」
みたいにしました。
しかし、これだけでは足りず、ファイルを書き込んだり削除できるようにするのと、ルートディレクトリ書き込み権限問題の対策も入れて、最終的にはこうなりました:

write_enable=YES
allow_writeable_chroot=YES
local_root=/var/www/html/path/to/target/directory

rootディレクトリに書き込めるようにしたものの、そもそもlocal_rootの定義で実ルートディレクトリを操作できるようにしているわけでなく、web公開ディレクトリの奥底深くを指定しているので、rootディレクトリを書き込みできる状態になっていても問題ないのです。

それぞれサービスをリスタート

二つのサービスの定義ファイルをいじったわけなので、それぞれ再起動させます。
「# systemctl restart sshd
「# systemctl restart vsftpd」

PostgreSQL:(作業メモ)データベースを別サーバー向けに複製したい

 現在業務に使っているサーバーはPostgreSQL 8.4で、これから引っ越すとおそらく最新は PostgreSQL 9.6だろうってことを想定して、実際にデータベース含めてシステムが引越しできるかを検討しているわけです。

現行サーバーで、pg_dumpallする

 「24.1.2. pg_dumpallの使用」に従って、現行サーバーのコンソール上で「pg_dumpall > outfile」ってやりました。
 こりゃ簡単だと思ったものの、何度か「Password:」なんてプロンプトが表示されて少しパニクりました。 結果的には、スーパーユーザーであるpostgresさんのパスワード入力要求でした。
 データベースをまるごとダンプするために、各データベース(テンプレートも含めて)に片っ端から接続(\connect)して構造を暴き出している感じでした。 outfileを見てみたらわかりました。

ロケールをこの際UTF-8にしておきたい

 現行サーバーのデータベースが、うっかりEUC_JPで作ってしまっていたので、これをこの際UTF-8に正したいと考えました。
 outfile をローカルにダウンロードしてテキストエディターで読み込みます。 でも、たまたま930MBくらいあるファイルサイズなので、そうやすやすと読み込めるエディターってないんですよ。 私はEmEditor (テキストエディタ)を使用しています。 巨大ファイルでもスルスル読み込めてストレスが無いんです。
 不要なDBユーザーに関する「CREATE ROLE」や「ALTER ROLE」や「GRANT」文もついでにカットします。 レンタルサーバーのサービスで自動的に登録された使用していないDBユーザーを継承しないためです。
 肝心の「CREATE DATABASE」文をチェックして、「ENCODING = 'EUC_JP'」から「ENCODING = 'UTF8'」に変更したり、「SET client_encoding = 'UTF8';」にしつつ、ファイルを保存するときのエンコードUTF-8(BOMなし)としました。 改行コードも「LFのみ」としました。

テスト環境はWindows10上にPostgreSQL 9.6.2-3 x64版

 配布されているインストーラー「postgresql-9.6.2-3-windows-x64.exe」を実行してインストールしました。 いや、その前にインストールするだけして全然使っていなかった 9.4をアンインストールして追加ソフト類も削除して、データベースファイル類も削除してからの、9.6インストールなのですけど。
 さて、いざ実行しようと、「psql -f infile postgres」をUSBメモリであるDドライブ上でコマンド プロンプトにて実行してみたところ動かない。 結果的には、「"C:\Program Files\PostgreSQL\9.6\bin\psql.exe" -f infile postgres postgres」となりました。 PostgreSQLインストール先にPATHが通っていないのでフルパス名で記述しました。 こういうのは面倒なので、システム環境変数PATHに「C:\Program Files\PostgreSQL\9.6\bin」を追加しておくと後でラクです。
 それと、わざわざ2つpostgresと書いているのは、一つ目はデータベース名で二つ目はDBユーザー名ということです。 二つ目のpostgresを省いて実行すると、Windows上のログインユーザー名を勝手に使って実行しようとして、そんなユーザーはいないみたいなエラーになってしまうための対策でした。
 ちゃんとデータベースが複製できているか、pgAdmin4を使ってスキーマを点検してみると、ちゃんと出来ているのが確認できてホッとしました。