Apache2 / PostgreSQL16を使ってログインユーザを管理しよう


Apache2を使ってユーザ認証するためにBasic認証を使う方法があります。 簡易的なら「.htpasswd」という便利なものがありますが、ユーザ数が多くなったりパスワード変更が 面倒になります。(私はなりました)
そこで、データベースを使って対応してみればよいかと思いました。
キーファイルはApache2.4系に標準で付いているmod_authn_dbdモジュールです。

OS : AlmaLinux9.2

参考サイト:Let's Postgres pgcrypto

使ったプログラム

アプリケーション名ファイル名
【apache2】 httpd.x86_64 2.4.53-11.el9_2.5
httpd-devel.x86_64 2.4.53-11.el9_2.5
mod_ssl.x86_64 1:2.4.53-11.el9_2.5
【postgresql】 postgresql16-server.x86_64 16.0-1PGDG.rhel9
postgresql16.x86_64 16.0-1PGDG.rhel9
postgresql16-libs.x86_64 16.0-1PGDG.rhel9
postgresql16-contrib.x86_64 16.0-1PGDG.rhel9
【pgsql】 apr-util-pgsql.x86_64 1.6.1-20.el9_2.1

  1. データベースの準備
    最初にユーザ情報を入れるデータベースの準備をします。
    必要な情報は「ID」と「パスワード」です。それ以外は好みで増やしてください。(漢字名やふりがな等)
    データベースについて
    ・データベース名login
    ・テーブル名idpw
    ・接続情報所有者:sslweb / パスワード:uebu
    権限:select / update / insert / delete
     テーブル内容
    ユーザ名userid text 重複禁止・空欄禁止
    パスワードpass text 空欄禁止
    手順
    1. pg_hba.conf を確認します
      linuxのシステムユーザ登録者の名称を利用の場合は問題が無いのですが、それ以外は以下の処理が必要です。
      【おすすめはできませんが、パスワードを省略することも可能です。イントラネットなら問題ないかと。】
      1. # su - postgres
      2. $ vi /var/lib/pgsql/16/data/pg_hba.conf
      3. パスワードを登録する場合はpeer認証だとエラーが発生するので修正します。
        大体112行目に以下のコメントがあります。
        # "local" is for Unix domain socket connections only
        local   all             all            peer  <--- ここを変更
                             ↓
        local   all             all            md5
        
      4. 変更したら保存し、終了します。 「:wq!」 もしくは 「ZZ」
      5. PostgreSQLを再起動します。
        $ exit
        # systemctl restart postgresql-16
        # systemctl status postgresql-16
        Active欄が 「active (running)」ならOKです。

    2. ユーザ登録
      ※インタビューモードが9.1以降、デフォルトでなくなりました。
      ロール権限を持ち、パスワードを暗号化して登録します。

      $ createuser --createrole --encrypted --pwprompt sslweb
      もしくは
      $ createuser -r -E -P sslweb
      【スイッチの解説】
      --createrole(-r) 新しいユーザにロール作成の許可を与えます。
      --encrypted(-E) ユーザーのパスワードを暗号化します
      --pwprompt(-P) パスワードを入力できます。

    3. データベースを作ります。
      $createdb login -O sslweb -W
      パスワード「uebu」を入力※非表示です
      【スイッチの解説】
      --owner(-O) 所有者
      --password(-W) 強制的にパスワードを促す

    4. ログインします。(パスワードを求められます)
      $psql login sslweb

    5. テーブルを作成します。
      login=> create table idpw (userid text primary key,pass text not null);

    6. sslwebユーザーに権限を与えます
      login=> grant select,update,insert,delete on idpw to sslweb;

      \du にてユーザ情報を確認できます。
      	login=> \du
      	                                       ロール一覧
      	 ロール名 |                                     属性
      	----------+------------------------------------------------------------------------------
      	 postgres | スーパーユーザー, ロール作成可, DB作成可, レプリケーション可, RLS のバイパス
      	 sslweb   | ロール作成可
      

      \dpにてテーブルごとの権限が確認できます。
        	login=> \dp
      	                               アクセス権限
      	 スキーマ | 名前 |  タイプ  |     アクセス権限      | 列の権限 | ポリシー
      	----------+------+----------+-----------------------+----------+----------
      	 public   | idpw | テーブル | sslweb=arwdDxt/sslweb |          |
      	(1 行)
      

  2. データベースの暗号設定
    暗号にはPostgreSQLのpgcryptoを使います。このプログラムはcontirbに収納されいています 。
    暗号化・複合化はPostgreSQLで処理をするため秘匿されますが、httpで通信するAPサーバ間の通信盗聴されてしまいます。
    この対策としてSSLを使いますが、それは別項で記載します。

    手順
    	最初に現状の拡張機能を確認
    	# su - postgres
    	$ psql login sslweb
    	ユーザー sslweb のパスワード:
    	psql (16.0)
    	"help"でヘルプを表示します。
    
    	login=> \dx
    	                    インストール済みの拡張一覧
    	  名前   | バージョン |  スキーマ  |             説明
    	---------+------------+------------+------------------------------
    	 plpgsql | 1.0        | pg_catalog | PL/pgSQL procedural language
    	(1 行)
    	
    	今インストールされている拡張機能のは『PostgreSQL Global Development Group』を基にデータベース言語SQLを拡張して開発された言語です。
    	
    	ここに暗号化・複合化の機能を追加します。
    	
    	login=> create extension pgcrypto;
    	CREATE EXTENSION
    	
    	追加できたか確認をします。
    	
    	login=> \dx
    	                    インストール済みの拡張一覧
    	   名前   | バージョン |  スキーマ  |             説明
    	----------+------------+------------+------------------------------
    	 pgcrypto | 1.3        | public     | cryptographic functions
    	 plpgsql  | 1.0        | pg_catalog | PL/pgSQL procedural language
    	(2 行)	
    
    	pgcrypto が増えています。これが、追加した拡張機能です。
    

  3. ユーザ情報を1件入れてみる サンプル ユーザ名:hoge / パスワード:word
    手順
    login=> insrt into idpw values('hoge',crypt('word',gen_salt('md5')));

    ここで「gen_salt」にエラーが出てきたら、上記の拡張機能が登録失敗している可能性があります。
    再度、上の項目を確認してください。
    「psql login sslweb」で対象のテーブルに入らず拡張機能を登録した場合、うまくいかないことがあります。

  4. ApacheからPostgreSQLのモジュールを呼び出せるように設定
    手順
    1. rootで処理をする
    2. # vi /etc/ld.so.conf
    3. # /usr/lib64 <-追加する
    4. # /sbin/ldconfig <-修正を反映させるために、ldconfigを再起動する

  5. Apache2の環境設定ファイルを設定
    1. 設定ホルダー:/etc/httpd/conf.modules.d/
      設定ファイル「01-dbd.conf」を自作します。
      下記の内容で作成してください。
      # vi 01-dbd.conf

      ---- 01-dbd.conf ----
      # mod_dbd configuretion
      DBDriver pgsql
      #DBDparams "host=ホスト名 dbname=データベース名 user=DBユーザ名 password=パスワード"
      DBDparams "host=localhost dbname=login user=sslweb password=uebu"

      DBDMin 4
      DBDKeep 8
      DBDMax 20
      DBDExptime 300
      ---- EOF ----
    2. 設定ホルダー:/etc/httpd/conf.d/
      WEBページ毎に環境設定ファイルを作ります。
      設定ファイル 「sslweb.conf」を自作します。
      下記の内容で作成してください。
      # vi sslweb.conf

      ---- sslweb.conf ----
      	# /etc/httpd/conf.d/sslweb.conf
      	# Basic authentication with PostgreSQL for encrypt
      
      	<VirtualHost *:80>
      	ServerName sslweb.usi.nu
      	ServerAdmin hogehoge@usi.nu
      	DocumentRoot "/var/www/sslweb"
      
      	<Directory "/var/www/sslweb">
      	    Options FollowSymLinks
      	    AllowOverride All
      	    Order deny,allow
      	    Allow from all
      
      	    # core authentication and mod_auth_basic configuration
      	    # for mod_authn_dbd
      	    AuthType Basic
      	    AuthName "sslweb"
      	    AuthBasicProvider dbd
      	    # core authorization configuration
      	    Require valid-user
      
      	# mod_authn_dbd SQL query to authenticate a user
      	AuthDBDUserPWQuery "SELECT pass FROM idpw WHERE userid = %s"
      
      	</Directory>
      	ErrorLog logs/error_log_sslweb
      	CustomLog logs/access_log_sslweb combined
      	</VirtualHost>
      
      ---- EOF ----
      ※「userid = $s」ですが、「$s」をシングルクォーテーションで囲まないように注意。

  6. Apacheを再起動する
      rootユーザで行う
    1. # systemctl restart httpd
      動作確認を行う
      # systemctl status httpd
      Active欄が 「active (running)」ならOKです。

確認のため、指定したフォルダをブラウザでアクセスし、ユーザ承認されて画面表示されればOKです。

2019/12/28 記述 VineLinuxで実施した記録
2023/10/04 Apache2.4 / PostgreSQL-16 で実施できるように書換え。

Let's PC の Topに戻る
ホームページのTopに戻る