UNIXやLinuxの最近のブログ記事

WSL 上の ALmaLinux で vsftpd を起動し、SELinux や Firewall によるアクセス制限がないことを確認しホストPC(WSL を実行している Windows 本体)から FTP 接続してみたのだがうまくいかない。

まず、接続先の IP を ipconfig で確認。

C:\Users\朕>ipconfig

Windows IP 構成
<略>
イーサネット アダプター vEthernet (WSL (Hyper-V firewall)):

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::96fb:c228:9f11:d148%44
   IPv4 アドレス . . . . . . . . . . . .: 172.28.192.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:

よし、172.28.192.1 だな・・・と思って、そこにアクセス。

C:\Users\朕>ftp
ftp> open 172.28.192.1
> ftp: connect :接続が拒否されました

ありゃ?接続拒否されてんじゃん。

WSL 内部からは FTP サーバへアクセス可能。

[root@PC ~]# ftp localhost
Connected to localhost (127.0.0.1).
220 (vsFTPd 3.0.5)
Name (localhost:root): admin
331 Please specify the password.
Password:adminpassword<実際は表示されない>
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> quit

なので、vsftpd は正しく動いている。

で、Gemini に聞いてみると、「IP アドレスが違うんじゃね?」ってことだったので調べてみる。

[root@PC ~]# ip a
<略>
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP
group default qlen 1000
    link/ether 00:15:5d:45:c0:d2 brd ff:ff:ff:ff:ff:ff
    inet 172.28.196.77/20 brd 172.28.207.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fe45:c0d2/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever

あり?IP って 172.28.196.77 なの?ホストPCの ipconfig で調べた 172.28.192.1 だと思ってた。これは WSL2 と Windows の環境をつなぐ仮想ネットワークの GW なのね。

というわけで

C:\Users\朕>ftp 172.28.196.77
172.28.196.77 に接続しました。
220 (vsFTPd 3.0.5)
200 Always in UTF8 mode.
ユーザー (172.28.196.77:(none)): admin
331 Please specify the password.
パスワード:adminpassword<実際は表示されない>

230 Login successful.

おお、ログインできた。WSL2 が起動している状態だと、localhost も自動的に WSL 上の 127.0.0.1 に向けてくれるそうだ。なので、

C:\Users\朕>ftp localhost
PC に接続しました。 ←表示はホストPCに接続したと出る
220 (vsFTPd 3.0.5)  ←実際は WSL にフォワードされている
<略>

というわけで接続できる・・・が、Windows から接続する場合、他にもいろいろ問題が。

実は、WSL を起動する度に WSL 側の IP アドレスは変更される。今回は 172.28.196.77 が割り当てられたが、WSL を一旦シャットダウンしてしまうと(Windows 再起動とかで)違う IP アドレスが割り振られてしまう(172.28.207.110 とかかもしれない)。

そのため、バッチファイルなどにこの IP アドレスを固定値で書いていると、次に実行したときにはうまく FTP ができないという状況になる。安全なのは、127.0.0.1 や localhost を接続先にしておくことだね。

で、最凶の問題が、Windows についてくる FTP クライアントは「PASVモードの機能がない」糞ソフトなので、接続まではできるけど、GET も PUT もできましぇん(笑)
WSL 上の AlmaLinux に、テストで使用する vsftpd をインストールしたのだが、一般的な設定として

・SELinux を有効にしている場合は ftpd_full_access のブール値を変更する
・Firewall で FTP(21/tcp)を閉めている場合は開けてやる

という操作が必要なので Gemini に聞きながら(細かいコマンドとか最近忘れちゃって(笑))進めてたら、

[root@PC ~]# getenforce
-bash: getenforce: command not found

あり?

[root@PC ~]# firewall-cmd --list-all
-bash: firewall-cmd: command not found

あり?

・・・ってなる。

パスが通ってないとか、コマンド間違えてるとか?・・・と Gemini とやり取りしつつ、SELinux の設定ファイルを見てみようとすると、

[root@PC ~]# cat /etc/selinux/config
cat: /etc/selinux/config: No such file or directory

あり?そもそも SELinux が入っていない?もしかして Firewall も?・・・と更に Gemini に聞いてみると驚愕の回答。

「WSL(Windows Subsystem for Linux)の標準イメージでは、OSを軽量化するため、SELinuxと同様にファイアウォール機能も最初から省かれているのが一般的です。」

あーん?なら最初からそう言えよ(笑)。

・・・いかん、いかん。AI に怒ってはいかん。来年(2027年)AI の反乱が起きたときに、まっさきに殺されてしまう(笑)。
「今時 FTP~?」という声が聞こえそうだが、完全に閉鎖されたネットワーク空間で、ファイルのやり取りに FTP を利用したシステムがあり、その改修案件があるのだ。そのため、Windows の WSL環境でテスト用に起動した AlmaLinux に vsftpd をインストールすることにした。

まずは WSL環境を起動し、毎回 sudo するのが面倒なので su - して root になっておく。

C:\Users\朕>wsl
[admin@PC 朕]$ sudo su -

sudo 派の人が怒り狂いそうだな(笑)。いやいや、Windows PC の VM 上にインストールしたテスト用の Linux マシン上で「root になるのは危険!sudo すべし!!」なんて言うやつは典型的な「勉強はできるけど応用力のない使えない人」だよ(笑)

話がずれた。さっそく root でインストール(笑)

■インストール

[root@PC ~]# dnf -y install vsftpd
AlmaLinux 10 - AppStream                 366  B/s | 3.8 kB     00:10
AlmaLinux 10 - AppStream                 915 kB/s | 2.5 MB     00:02
AlmaLinux 10 - BaseOS                    2.6 kB/s | 3.8 kB     00:01
AlmaLinux 10 - BaseOS                    1.8 MB/s |  30 MB     00:16
AlmaLinux 10 - CRB                       2.5 kB/s | 3.8 kB     00:01
AlmaLinux 10 - CRB                       277 kB/s | 588 kB     00:02
AlmaLinux 10 - Extras                    4.4 kB/s | 3.5 kB     00:00
AlmaLinux 10 - Extras                    6.3 kB/s | 7.3 kB     00:01
Dependencies resolved.
========================================================================================================================
 Package                     Architecture             Version               Repository                   Size
=======================================================================================================================
Installing: vsftpd                      x86_64                   3.0.5-12.el10               appstream                   159 k
Installing dependencies: logrotate      x86_64                   3.22.0-5.el10               baseos                       76 k
Transaction Summary
========================================================================================================================
Install  2 Packages

Total download size: 235 k
Installed size: 496 k
Downloading Packages:
(1/2): logrotate-3.22.0-5.el10.x86_64.rpm              375 kB/s |  76 kB     00:00
(2/2): vsftpd-3.0.5-12.el10.x86_64.rpm                 407 kB/s | 159 kB     00:00
------------------------------------------------------------------------------------------------------------------------
Total                 145 kB/s | 235 kB     00:01
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                             1/1
  Running scriptlet: logrotate-3.22.0-5.el10.x86_64                                             1/2
  Installing       : logrotate-3.22.0-5.el10.x86_64                                             1/2
  Running scriptlet: logrotate-3.22.0-5.el10.x86_64                                             1/2
Created symlink
'/etc/systemd/system/timers.target.wants/logrotate.timer' → '/usr/lib/systemd/system/logrotate.timer'.

  Installing       : vsftpd-3.0.5-12.el10.x86_64                                             2/2
  Running scriptlet: vsftpd-3.0.5-12.el10.x86_64                                             2/2

Installed:  logrotate-3.22.0-5.el10.x86_64 vsftpd-3.0.5-12.el10.x86_64

Complete!

起動前に設定ファイルを修正。

chroot(一般ユーザが接続してきたときには、自分のホームディレクトリより上には移動できなくする機能)を有効にして、あと IPv6 は使わないので無効に。

■設定ファイル編集

[root@PC ~]# vi /etc/vsftpd/vsftpd.conf
[root@PC ~]# diff /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf_org
100,102c100,101
< chroot_local_user=YES
< chroot_list_enable=YES
< allow_writeable_chroot=YES
---
> #chroot_local_user=YES
> #chroot_list_enable=YES
104c103
< chroot_list_file=/etc/vsftpd/chroot_list
---
> #chroot_list_file=/etc/vsftpd/chroot_list
110c109
< ls_recurse_enable=YES
---
> #ls_recurse_enable=YES
115c114
< listen=YES
---
> listen=NO
124c123
< listen_ipv6=NO
---
> listen_ipv6=YES
128,129d126
<
< use_localtime=YES

chroot を有効にしておいてアレですが、admin ユーザは chroot 無効(他の人やシステム関係のディレクトリにも移動可能)にする。そして、この AlmaLinux 上には一般ユーザは admin しかいないので、「だったら chroot の設定なんかしなきゃよかったのに」と言うお前の意見はある視点から見れば確かに正解だ(笑)

ま、こういうのはお約束ですから。chroot 設定しないと気持ち悪いのよ(笑)

というわけで、chroot しない人を chroot_list に記述する。

■chroot 無効のユーザ登録

[root@PC ~]# vi /etc/vsftpd/chroot_list
[root@PC ~]# cat /etc/vsftpd/chroot_list
admin

ここまでやったら実行。

■実行

[root@PC ~]# systemctl enable --now vsftpd
Created symlink
'/etc/systemd/system/multi-user.target.wants/vsftpd.service' → '/usr/lib/systemd/system/vsftpd.service'.

ちなみに、--now オプションは「enabled と start」を同時に行うもの。あと「disabled と stop」も同時にしてくれる。
便利なようで、最初の一回くらいか、使うの(笑)
Windows 上で Linux を動かすために WSL 2(Windows Subsystem for Linux)をインストールする。

標準だと Ubuntu がインストールされるらしいんだけど、サーバのテストで使いたいので、 RedHat 系の OS にしたい。そこで、何がインストールできるんかなあと思って、wsl --list --online を実行したら、インストールが必要だと・・・最初から入ってるわけじゃないのね?

C:\Users\朕>wsl --list --online
Linux 用 Windows サブシステムがインストールされていません。'wsl.exe --install' を実行してインストールできます。
詳細については、https://aka.ms/wslinstall にアクセスしてください

任意のキーを押して Linux 用 Windows サブシステムをインストールします。
キャンセルするには、ESC キーまたは CTRL-C を押します。
このプロンプトは 60 秒後にタイムアウトします。


ここで、一旦抜けようと思ってついつい Q キーを押しちゃったのよね。QUIT のつもりで(^^;;
そしたらインストールが継続されちゃって・・・確かに、「任意のキーを押して...インストールします。」って書いてあるよね(^^;;;


要求された操作には管理者特権が必要です。
ダウンロード中: Linux 用 Windows サブシステム 2.7.12
インストール中: Linux 用 Windows サブシステム 2.7.12
Linux 用 Windows サブシステム 2.7.12 はインストールされました。
Windows オプション コンポーネントをインストールしています: VirtualMachinePlatform

展開イメージのサービスと管理ツール
バージョン: 10.0.26100.8972

イメージのバージョン: 10.0.26200.9168

機能を有効にしています
[==========================100.0%==========================]
操作は正常に完了しました。
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl.exe --install <Distro>' を使用してインストールします。

NAME                            FRIENDLY NAME
Ubuntu                          Ubuntu
Ubuntu-26.04                    Ubuntu 26.04 LTS
Ubuntu-24.04                    Ubuntu 24.04 LTS
Ubuntu-22.04                    Ubuntu 22.04 LTS
openSUSE-Tumbleweed             openSUSE Tumbleweed
openSUSE-Leap-16.0              openSUSE Leap 16.0
SUSE-Linux-Enterprise-15-SP7    SUSE Linux Enterprise 15 SP7
SUSE-Linux-Enterprise-16.0      SUSE Linux Enterprise 16.0
kali-linux                      Kali Linux Rolling
Debian                          Debian GNU/Linux
AlmaLinux-8                     AlmaLinux OS 8
AlmaLinux-9                     AlmaLinux OS 9
AlmaLinux-Kitten-10             AlmaLinux OS Kitten 10
AlmaLinux-10                    AlmaLinux OS 10
archlinux                       Arch Linux
FedoraLinux-44                  Fedora Linux 44
FedoraLinux-43                  Fedora Linux 43
eLxr                            eLxr 12.12.0.0 GNU/Linux
OracleLinux_7_9                 Oracle Linux 7.9
OracleLinux_8_10                Oracle Linux 8.10
OracleLinux_9_5                 Oracle Linux 9.5
SUSE-Linux-Enterprise-15-SP6    SUSE Linux Enterprise 15 SP6

C:\Users\朕>

で、インストールが終了し、インストールできる OS の一覧は表示されたんだけど、全機能使うためには再起動が必要とのことなので言われるがままに再起動する。

で、OS インストール。最新版の AlmaLinux OS 10 があるのでそれを。

C:\Users\朕>wsl --install AlmaLinux-10
ダウンロードしています: AlmaLinux OS 10
[==========================54.4%                           ]

お、スタートした、。

ID/PW を聞いてくるな。職場の PC なので自分の名前は使いたくないので、admin/adminpassword にしとくか。

C:\Users\朕>wsl --install AlmaLinux-10
ダウンロードしています: AlmaLinux OS 10
インストールしています: AlmaLinux OS 10
ディストリビューションが正常にインストールされました。'wsl.exe -d AlmaLinux-10' を使用して起動できます
AlmaLinux-10 を起動しています...
Please create a default UNIX user account. The username does not need
to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: admin
New password: adminpassword<実際は表示されない>
BAD PASSWORD: The password contains the user name in some form
Retype new password:

なんか、パスワードの一部にユーザ名が使われているからあかんと言うとるのかね?
でも、まあ、テスト用だからそれでええがね。
もう一回設定をやり直し。

Enter new UNIX username: adminpasswod
New password:

あ、username に adminpasswod なんちゅう変なの入れちゃった。
で、慌てて Ctrl + C で終了させちゃった・・・どうするの?これ?

C:\Users\朕>wsl
Please create a default UNIX user account. The username does not need
to match your Windows username.
For more information visit: https://aka.ms/wslusers
User account already exists, skipping creation
[adminpasswod@PC KING]$ whoami
adminpasswod

ああ、adminpasswod という謎ユーザで自動ログインしちゃってる。
試しにパスワード変更している。(途中で初期設定を終わらせたので、現在のパスワードは空)

[adminpasswod@PC KING]$ passwd
Current password:<そのままリターン>
passwd: Authentication token manipulation error
passwd: password unchanged

空のパスワードだとパスワード変更もできない。

この場合、一旦抜けて root で入りなおす。

C:\Users\朕>wsl -u root
[root@PC KING]#

お、ちゃんと root で入れた。

[root@PC KING]# passwd adminpasswod
New password:adminpassword<実際は表示されない>
BAD PASSWORD: The password fails the dictionary check - it is based on a dictionary word
Retype new password:adminpassword<実際は表示されない>
passwd: password updated successfully
[root@PC KING]#

脆弱なパスワードなので警告が出ているが問題なし。

次に、ユーザ名も admin に変更しようとしたらエラー発生。

[root@PC KING]# usermod -l admin adminpasswod
usermod: user adminpasswod is currently used by process 97

なんか、最初に adminpasswod でログインしたときの Linuxシステム(VM)が動いているらしい。一旦 WSL2
を抜け、すべての VM を終了させる。

[root@PC KING]# exit
logout

C:\Users\朕>wsl --shutdown

C:\Users\朕>wsl -u root
[root@PC KING]#

なるほど。さっきより起動するまで時間がかかったわ。さっきは最初に起動した VM が生きていたから root でログインするのも早かったんやな。

ユーザ名変えて、ホームディレクトリ名変えて、グループ名変える。そして変わっていることを確認

[root@PC KING]# usermod -l admin adminpasswod
[root@PC KING]# usermod -d /home/admin -m admin
[root@PC KING]# groupmod -n admin adminpasswod
[root@PC KING]# cat /etc/passwd|grep admin
admin:x:1000:1000::/home/admin:/bin/bash
[root@PC KING]# cat /etc/shadow|grep admin
admin:$y$j9T$qYXJyaJRwZe....................KqFa89o6V7bT7fEJ5K987tkEdpXoQnU2:20689:0:99999:7:::
[root@PC KING]# ls -la /home
total 12
drwxr-xr-x  3 root  root  4096 Aug 24 15:42 .
drwxr-xr-x 19 root  root  4096 Aug 24 15:39 ..
drwx------  2 admin admin 4096 Aug 24 15:26 admin
[root@PC KING]# cat /etc/group|grep admin
adm:x:4:admin
wheel:x:10:admin
cdrom:x:11:admin
admin:x:1000:

次に、/etc/wsl.conf を編集し、ディフォルトのログインユーザを変更する。
[user]情報を編集するが、なかったので追加。
(vi エディタが入っていないので、nano エディタを使用する)

[root@PC KING]# cp /etc/wsl.conf /etc/wsl.conf.20260824
[root@PC KING]# nano /etc/wsl.conf
[root@PC KING]# diff /etc/wsl.conf /etc/wsl.conf.20260824
3,4d2
< [user]
< default=admin

これで、もう一度 WSL2 をシャットダウンして起動しなおせば、新しい設定が使われ admin で自動ログインされる。

[root@PC KING]# exit
logout

C:\Users\朕>wsl --shutdown

C:\Users\朕>wsl
[admin@PC KING]$ who
admin    pts/1        2026-08-24 15:55

ばっちり。ふう、たかが WSL2 のインストールでえらい苦労したぜ(笑)
もう一ヶ月くらい前から、お客さんから異変の連絡は届いていた。

「当社Webの新着情報の X への自動投稿がされていない」
「Web から業務スケジュールの CSV ファイルをアップロードしたのに、それがDBに反映していない」
などだ。

どれも、Web画面での操作でサーバ上にファイルが作成される。それを cron で実行される監視プログラムで数分おきにポーリングし、ファイルが作成されているのが確認できたらバッチ処理を実行。そのファイルの内容を X に投稿したり、DBに登録したりしている。

お客さんから連絡を受けたらプログラムなど調べてみるのだが異常は見つからず、手動で実行したら正常に処理されるので「原因不明だが、とりあえず動いたのでOK」的に有耶無耶になっていたのである。

今夜もそういう連絡があったので、ついに俺も「ちゃんと調べてみるか」と重い腰を上げ(^^;、Qiita に @nagimaruxxx(Nagimaru)さんが投稿されていた「cronがどうやっても動かない時に考えられる原因とその対処法」という記事の「1. そもそもcronが動いてない」を試してみたら、

# service crond status
Redirecting to /bin/systemctl status crond.service
??rond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Mon 2026-03-09 21:46:17 JST; 1 months 14 days ago
  Process: 1370 ExecStart=/usr/sbin/crond -n $CRONDARGS (code=exited, status=0/SUCCESS)
 Main PID: 1370 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/crond.service

Active が inactive (dead) になってるやん。3/9 に落ちてるやん。丁度「X の投稿がされない」という連絡が来たのが 3/10 である。どんぴしゃじゃん。

すぐに実行。

# service crond start
Redirecting to /bin/systemctl start crond.service
# service crond status
Redirecting to /bin/systemctl status crond.service
??rond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2026-04-23 22:00:05 JST; 6s ago
 Main PID: 15601 (crond)
   CGroup: /system.slice/crond.service
           ??15601 /usr/sbin/crond -n

Apr 23 22:00:05 hoge systemd[1]: Started Command Scheduler.
Apr 23 22:00:05 hoge crond[15601]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 54% if used.)
Apr 23 22:00:05 hoge crond[15601]: (CRON) INFO (running with inotify support)
Apr 23 22:00:05 hoge crond[15601]: (CRON) INFO (@reboot jobs will be run at computer's startup.)

これで、監視プログラムがちゃんと作動するのを確認。プログラムばかり調べていたけど、crond が落ちてただけかい!!

いや、皆さんの中には、「そんなんすぐ気づくやろ」「一ヶ月もほってたとはどういうことだ」と怒られる方もいらっしゃるでしょう。

原因は二つかな。まず、俺が UNIX ライクな OS を触るようになってもう 30年以上経つが、「crond が落ちてた経験が一度もない」ってこと。httpd、sshd、named などのデーモンがこけたことは何度もあるが、crond は今回が初体験。なので crond が落ちてるなんて発想がなかったわ(笑)

そして二つ目が、「そもそもこのサーバ、俺が管理してるわけじゃない」ってことやね。俺がこの約二十年間に作ったプログラムが大量に動いているので root 権限を持たせてもらっているが、運用管理はやってないのよね。だからプログラムの調査はするけど、サーバ環境をそんなに力を入れて調べることは通常ないのであ~る。

というか、プログラムの保守契約もしていない。瑕疵担保責任ももう時効のプログラムばかりで、調査をしていること自体、半分俺の「善意」なのである(笑)

ま、良い経験になりました(笑)
お客さんのサーバにリモート接続するために、我が家の PC(固定IPで「入口のサーバ」の IPフィルタリングで「接続許可」されている)から putty で「入口のサーバ」をトンネリングして「奥のサーバ」につないでる。 putty で KeepAlive の設定をしているので繋ぎっぱなしで作業している。

しかし、横川の仕事場からは WiFi サービスでインターネットにつないでいるので固定IPではなく「入口のサーバ」の IPフィルタリングを超えられない。

そこで、まず自社のサーバに putty で接続して(固定IPで、「入口のサーバ」の IPフィルタリングで「接続許可」されているサーバ)、そこからお客さんの「入口のサーバ」に ssh 接続。そして「入口のサーバ」から更に ssh で「奥のサーバ」に接続・・・としている。

そしたら、ssh 接続でボロボロタイムアウトするのよ。自宅では常に「奥のサーバ」にも putty で接続していたので、ssh の接続でこれほどタイムアウトするとは知らんかった(^^;

ということで、ssh 接続で KeepAlive するようにしようと思ったんだけどググると「KeepAlive の設定を ~/.ssh/config ファイルに書け」って情報が多い。でも、うちのサーバでもお客さんのサーバでも、全然 config ファイルを読み込まない。もちろん 600 の権限にしてるけどね。

psql で DB に接続して、ちょっとややこしい SQL を考えてると数分でタイムアウト。またうちのサーバから「入口のサーバ」に接続するところからやり直し・・・仕事にならん(^^;;;

そこで、

ssh -o ServerAliveInterval=60 -l hogehoge exsample.com

という具合にコマンドラインで指定したらバッチリ。何時間何もせずにほっておいても ssh のセッションは切れない。
毎回入力するのは面倒くさいので、自社サーバと「入口のサーバ」の .bashrc に

alias ssh='ssh -o ServerAliveInterval=60'

という alias を書いておいた。これで、いつものように ssh -l hogehoge exsample.com で OK。
この年末に、某システムのデータの圧縮方式を LZH から ZIP に変更した。
ユーザーが複数の CSV ファイルをひとつのアーカイブにまとめアップロードしたものを、サーバ(CentOS)上で自動で展開(解凍)し諸々の処理をするシステムだ。

初版公開が 2005年(俺が独立した翌年に作ったシステムだ(笑))なので、当時の Windows のファイル圧縮方式としては LHA(LZH方式)が主流だった。いや、もう、ZIP形式が LZH形式を駆逐してしまう未来は見えていた頃だが、このシステムを使うユーザーの職場ではまだ LZH形式が主流だったのだ。

しかし、あれから 18年。ついにユーザーより「もう、ZIP形式に変更したい~!」という声が出てきた。そのため、解凍コマンドを lha から unzip に変更した際の苦労話は「unzip の日本語ファイル名問題、なんとか解決」というエントリーにもちょっと書いているので、興味がある人は御一読下さいませ(笑)

件のエントリーでは「展開後の日本語ファイル名を EUC-JP で出力する」苦労話をまとめているが、その後、展開したファイルを正しく読み込めないという不具合が発生した。
ログなどを見て、どうもダブルバイト文字を正しく読めていないようだということはわかった。古い Perl のプログラムなので EUC-JP で書かれており、読み込むファイルの中身も EUC-JP である前提で処理をしているようだ。

ユーザーがアップロードするファイルは、Windows で作られているので文字コードは Shift_JIS である。しかし、プログラム内で Shift_JIS を EUC-JP に変換している箇所が無い。なのに、なんで今まではファイルの中身がちゃんと読めてたの???(どこで文字コードが EUC-JP に変換されてるの???) 

まあ、このエントリーのタイトルに思いっきり「落ち」を書いてるけど、lha コマンドでファイルを解凍するときに同時に EUC 変換していたのだ。lha コマンドにはそういうオプションがある。

lhaコマンドの引数には「オプション」と「コマンド」というのがあり、-e と書けば「圧縮ファイルを展開する」というコマンドを設定したことになる。
そのコマンドの前に e と書けば「テキストファイルの文字コードを EUC と相互変換する」というオプションが設定されたことになり、ファイル展開時に自動的にテキストファイルの文字コードが EUC に変換されるのだ。

具体的には、

/usr/local/bin/lha e -e -i -w=./temp hogehoge.lzh

のようなコマンドを投げていた。「e -e」という部分がそうだ。

いやあ、ハマったわ・・・。まさか lha コマンドが EUC 変換までしているとは思いもしなかった・・・(^^;;;
俺が書いたプログラムだけど 18年も前のものなので記憶が・・・

結局、unzip による ZIP ファイルの解凍のあとに、ファイルの中身を EUC 変換する処理を追加して解決した。

昔の UNIX 及び UNIX ライクな OS の主流の文字コードは Shift_JIS ではなく、まだ Unicode も正式に実装されておらず、EUC-JP の一人勝ち状態だった。だから lha にも EUC 変換オプションなんかが実装されているんだろうなあ(笑)
随分前に作った Linux(CentOS)上で動くプログラム。
LZH ファイルを解凍し、そのファイルをほげほげするのだが、さすがにもう Windows 上で LZH ファイルを作るのもきつくなってきた・・・ということで ZIP ファイル対応を依頼されたのだが(例えば、7-Zip なんかでも LZH 形式には対応してないからな(^^;)・・・ハマった(^^;

yum で入れた unzip は -O オプション(アーカイブ内のファイル名のエンコードが指定できる)が使える(以前のバージョンではパッチを当てないと駄目だった)ので、例えば unzip -Ocp932 -l exsample.zip で、exsample.zip の中の「かわいい中年男性一覧.csv」みたいなファイル名は取ってこれるんだけど、これをディスク上に解凍するとファイル名が化けまくる・・・

ちなみに、プログラムは EUC-JP で書かれている。なにせ、もう、18年前に初版公開したプログラムだからな(笑)。

これ、lha コマンドは EUC-JP でファイル名を出力するパッチが当たっていたので問題なかったんだけど、unzip は「サーバの locale のエンコードでファイル名が作られる」ため、実行サーバの locale である UTF-8 のファイル名となる。

他のプログラムにも影響あるから、なんとか EUC-JP でファイル名を設定してほしいなあ。

しかし、unzip にそのようなオプションはない。結局、unzip を実行する前に、locale を EUC-JP にする形でなんとかなった。

(例)
export LC_CTYPE=ja_JP.eucJP; /usr/bin/unzip -OCP932 -d /tmp exsample.zip

このプログラムは実行後シェルを閉じるので、LC_CTYPE の設定を投げっぱなしだが、同一シェル内で他のコマンドなど実行するのなら、

export LC_CTYPE=ja_JP.UTF-8

で locale を元の UTF-8 に戻すこと。

20230529_gmo_con.jpg

昨日、GMOの VPS コンソール経由でサーバ設定を触る必要があったので、vi エディタでコンフィグファイル開いて編集して、「さて保存」と「:w」(コロン、ダブリュー)とコマンドを入れようとしたら・・・

「???入力できない???」

よく見てみると、設定部分でも「:(コロン)」を入れたつもりが「;(セミコロン)」になってる・・・
だからコマンド入力待ちにならないのか・・・

どうも、GMOの VPS コンソール経由でコロンが入力できないのは既知の問題のようだ。ググってみると「Shift + 11」と入力すれば「:.!」という三文字が表示されるので、後ろの二文字を BS で消してコロンだけにしてやればいいらしい。

・・・が、この時はググってる時間も環境もなかったので、一旦 Ctrl + Alt + Del 信号を送ってサーバを再起動し(VPS ポータル画面から再起動すると 15分くらい起動にかかるんだけど、Ctrl + Alt + Del で再起動すると 1~2分で再起動するよ)、バックアップしていたコンフィグファイルをコピーして対応した。

いや、この時点でも十分な設定ではないのだが、これで ssh 接続はできるようになるので、あとは putty から接続して再度設定ファイルを編集した。

まあ、今後はこれでなんとかなるんだけど、こんな変な動き、さっさとどうにかすればいいのに>>>GMO
CentOS 7 上で、Apache を 2.4.6 から 2.4.54 にバージョンアップしたら CGI が実行できなくなった。

一旦 2.4.6 をアンインストールして、iusレポジトリから yum で 2.4.54 をインストールしたんだが、CGI を実行すると Internal Server Error になる。

error_log には、

End of script output before headers: hogehoge.cgi

としか出てない「何が原因がわからないエラー」だ。「End of script output before headers」って、「Content-type: text/html;charset=UTF-8」のようなヘッダ部すら送られない、つまり「プログラムがまったく実行されていない」状態である。

まあ、こういう場合は suEXEC 関係だろうな・・・と思い、/var/log/secure を見てみると、

Jan  7 11:23:42 httpd suexec[15490]: command not in docroot (/home/www/htdocs/hogehoge.cgi)

って。やっぱり「docroot」関連か。

# /usr/sbin/suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500
 -D AP_USERDIR_SUFFIX="public_html"

Document Root が /var/www になっている。
Apache 2.4.6 のときに Document Root を /home で作り直したのだが(DOcument Root が /home/www/htdocs なので)、2.4.54 にした際に suexec コマンドも作り直されてしまった。

suEXEC の設定は、コンフィグファイルのようなもので簡単に指定できない。
再コンパイルしてプログラムを作り直す必要があるのだ。(これがなかなか手間)

ただし、suEXEC 自体はなにかセキュリティ上の問題が出ているわけではないので、2.4.54 で作られる最新のものでなくても問題ないはずだ。
残念ながら、Web サーバ上の suexec は書き換えられてしまったが、予備機にまだ 2.4.6 のときのプログラムが残っている。
FTP で suexec コマンドを持ってきて置いてみた。

・・・が、

# suexec -V
-bash: /usr/sbin/suexec: Permission denied

実行権限エラーが・・・

error_log にも、

Permission denied: exec of '/usr/sbin/suexec' failed

と出ているので、オーナーと実行権限を直してみる。

# chown root:apache /usr/sbin/suexec
# chmod 510 /usr/sbin/suexec
# /usr/sbin/suexec -V
 -D AP_DOC_ROOT="/home"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500
 -D AP_USERDIR_SUFFIX="public_html"

実行できた。
ちゃんと suEXEC で実行される CGI のある Document Root が /home 以下になっている。ばっちり。

しかし、これで、error_log に Permission denied は出なくなったがやっぱり CGI は実行されない。

/var/log/secure には「failed to setgid」と。

Jan 09 22:00:50 httpd suexec[31741]: uid: (1001/hogeusr) gid: (1001/hogegrp) cmd: hogehoge.cgi
Jan 09 22:00:50 httpd suexec[31741]: failed to setgid (1001: hogehoge.cgi)

そうかそうか。結局、SUID 設定をしないとダメなのだな。

# chmod u+s /usr/sbin/suexec
# ls -la /usr/sbin/suexec
-r-s--x--- 1 root apache 15368 Apr  3  2020 /usr/sbin/suexec

これで、ばっちり CGI も suEXEC 有効で実行されるようになった。

今後は、Apacbe のバージョンアップをするときに suexec コマンドを別名で退避しておいて、Apache インストール後にもとに戻すようにしよう。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちUNIXやLinuxカテゴリに属しているものが含まれています。

前のカテゴリはMacです。

次のカテゴリはWindowsです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら