Linuxのログイン時の環境変数の読込順

順番

  1. /etc/profile
  2. /etc/profile/profile.d配下
  3. ~/.bash_profile 
  4. ~/.bash_login
  5. ~/.profile
  6. ~/.bashrc
  7. /etc/bashrc

補記事項

  • /etc/profile/profile.dはディレクトリで、その配下にあるスクリプト内で定義
    • RHEL/CentOSは何も置いてないイメージ
    • ubuntuは結構もっさりあるイメージ
  • .bash_profile, .bash_login, .profileはもしかしたらどれか読み込んだら、他を読み飛ばすかも(きちんと実験していないので分からない)

その他配慮ポイント

  • サービスやcronで実行される場合は上記ファイルを参照しない
  • /etc/environmentで定義されている場合、それが読み込まれる(※1)
  • crontabのPATHは/etc/crontab内に定義されている場合がある(※2)
  • /etc/sudoersのsecure_pathはsudo実行時のみ上書きされる(cron実行時には評価されない)
  • suコマンドに-オプション付けてログインしている時としていない場合でも変わる
  • systemdのユニットファイルに定義されている場合がある
  • /etc/locate.conf で定義されている場合がある
  • それ以外にもスクリプトのどこかで上書きされている場合がある
  • 追記されている場合もあれば、上書きされている場合もある
  • 手動実行時とサービス等での実行時では変わる要素ありすぎるため、必ずテストすること
  • 必ず、必ずテストすること(2度目)

※1 参照される主なシーン
・システムサービス
・実行中のデーモン

※2 /etc/crontabに定義されている例(※3)

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
(以下略)

※3 CentOSでは定義されていること多いが、ubuntuでは定義されていない様な気がする

SAML認証が急に400エラーが発生する様になった

事象

SAML認証が急に400エラーが発生する様になった。

400 Bad Request
Your browser sent a request that this server colud not understand.

証明書の期限切れを疑ったが、どちら(※1)もOKであった。

※1 以下2つのどちらかの期限切れを当初疑っていた

  • SAML自体の証明書
  • Apache(※2)でhttps通信にするための証明書

※2 便宜上Apache HTTP ServerをApacheと以後も記載

SAMLのレスポンスを確認したところ、以下の様に問題なかった。
そのため、Idp側までは正しく認証が行えていると判断し調査を進めた。

(中略)
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />

原因

サーバーの時刻がずれていただけであった。。。(※3)

該当サーバはApache + mod_auth_mellonにてSAML認証を実現している。
Apacheのログを確認すると、以下の様なログが出力されていた。

auth_mellon:error NotBefore in Condition was in the future

当エラーログに関しては、mod_auth_mellonのマニュアルに言及があった。
mod_auth_mellon User Guide

10.9. Time Sync
SAML, like many authentication protocols (e.g. Kerberos), relies on timestamps to validate messages. If you see one of these errors in the httpd logs:

[auth_mellon:error] [pid xxx] [client xxx] NotBefore in Condition was in the future.
[auth_mellon:error] [pid xxx] [client xxx] NotOnOrAfter in Condition was in the past.

※3 約8分ほどずれていた

Chromeでアクセスするとたまに英語で表示されるサイトがある

事象

ごくたまにAzureのログイン画面が以下の様に英語で表示されてしまう。

何故か英語で表示される

Azureの他のサイトは日本語で表示されているのに、ログイン画面だけ英語になる。
また、何度か色々な画面遷移していると日本語表示に変わった。

原因

対応方法・解説

Chromeの設定

確認したところ言語の設定が以下の様になっていた。

上記設定の場合、英語で表示できるサイトは英語になる

この優先順位とは、HTTPリクエストヘッダーのaccept-languageに相当する設定と思われる。
そのため、英語表示行えるサイトはこれに従い英語表記となる。
但し、この設定が正しく評価して表示するサイトはごく少数な気がする。
(私の知っている限りは、はてなブログツールバーの一部および管理者画面、Amazonセラーセントラル位)
よって、優先言語を日本語を第一位に設定すれば無事解決した。

Cookieの設定

上記優先言語の設定を変更せずとも、日本語に切り替わったケースがあった。
これは、多分Cookieに表示するための情報を保持されたためと思われる。
そのため、シークレットモードで再度アクセスすると、英語表示に戻ってしまった。
よって、恒久的な対応としては、上記の通り優先言語設定を日本語にする必要がある。

Chromeの日本語表示

優先言語の三点リーダーを押すと、「Google Chromeをこの言語で表示」という設定がある。
これは、Chromeの各種部分をその指定した言語で表示する機能である。
この設定自体は、サイトを日本語で表示するための機能は直接的には存在しないと思われる。(※1)

※1 但し、当設定をチェックすると言語の優先順位も先頭に入れ替わった。
よって、当設定を行うことで優先順位も同時に設定されるというのが正しい理解と考えている。

Seleniumでの対応方法

上記より、Seleniumで--lang=jaと指定しているのは、上記のChromeの日本語表示と思われる。
また、どうもSleniumは、言語の優先順位は英語が第一位のままな気がする。
そのため、日本語サイトをアクセスする正しい設定は以下の様な実装が必要と考える。(※2)

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from splinter.driver.webdriver import BaseWebDriver, WebDriverElement

option = Options()
option.add_experimental_option('prefs', {'intl.accept_languages': 'ja'})
option.add_argument('--lang=ja-JP')
driver = webdriver.Chrome(options=option)
(以下略)

※2 但し、コードの一部の抜粋 & 実際に動かしていないコードである。

後日談

しかしながら、上記を施しても駄目なサイトが存在した。
そのサイトはアクセスしてきたサイトのIPを判定して、言語設定を行う実装がなされていた。
IP偽装も考えていたが、クエリーパラメータで指定できる対応もなされていた。
よって、https://~/?hoge=jaみたいなのを追加することで対応できた。

topコマンドをcronで仕込みたい

行いたいこと

sysstatでCPUが一時的に高騰していることが分かった。
しかし、何がリソース喰っているのか分からなかった。
そのため、cronで top の実行結果を継続的に保管したい。

実施した内容

crontabに仕掛けた内容
*/1 * * * * root top -b -d 1 -n 1 > /var/log/top/result.txt_`date "+\%Y\%m\%d_\%H\%M\%S"`
補記事項
  • 事前に/var/log/topというフォルダを穴掘り
  • そのフォルダに年月日時分秒を付与したファイルが1分当たりで生成
  • オプションの内訳

 ・-b:バッチモードで実行
 ・-d:実行間隔[秒](今回は1回実行なので意味は無い)
 ・-n:実行回数

  • crontabで書く際には、dateの出力フォーマットに使う%は\でエスケープする必要有
  • 自身の環境では1日で300MB位使っていたので、ログローテート or 不要時は停止が必須

生成されたファイルの使い道

  • 串刺しで確認して、やばそうな時間帯を見つける(sysstat側で見てもいいけど)
  • その後、該当時間のファイルの前後などをちまちま確認
  • 対象のPIDなどをキーにgrepして推移確認

dateはJST表記なのに、syslogはUTC表記になる

事象

dateコマンドの実行結果はJSTである。
なのに、syslogのログの日付はUTCである。

原因

ロケールは日本語になっているが、タイムゾーンUTCのままなので。

date
2023年  1月 27日 金曜日 23:54:09 JST 

localectl status
System Locale: LANG=ja_JP.UTF8        
VC Keymap: n/a       
X11 Layout: us        
X11 Model: pc105 

timedatectl
Local time: 金 2023-01-27 14:55:48 UTC
Universal time: 金 2023-01-27 14:55:48 UTC
RTC time: 金 2023-01-27 14:55:47
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

対応方法

timedatectlでタイムゾーンを設定し、再起動する。

timedatectl set-timezone Asia/Tokyo

timedatectl status
Local time: 金 2023-01-27 23:55:34 JST
Universal time: 金 2023-01-27 14:55:34 UTC
RTC time: 金 2023-01-27 14:55:33
Time zone: Asia/Tokyo (JST, +0900) System clock synchronized: yes
NTP service: active
RTC in local TZ: no 

reboot ← 再起動しておく方が確実

crontab内でdateコマンドがうまく動かない

事象

crontab内で出力ファイルに日付を付与したかった。
そのため、dateコマンドを利用したいが、以下が詰まった。

  • "+%Y%m%d_%H%M%S" 部分がcron内ではエラーになる
  • cronで実行するとJSTではなくUTC実行になる

対応方法

フォーマットの問題

\でエスケープする必要がある。
qiita.com

cronでJSTではなくUTCになる

実行ユーザーの環境変数TZがUTCである。
変更すれば一番てっとり早いがこれだけのために変えたくない。
通常の実行であれば、以下で変更可能である。

TZ=JST date

しかしながら、どうもcron内ではTZの評価は揮発するみたいである。
そのため、dateを実行しただけとなり、UTCとして出力されてしまう。
多少強引ではあるが、時間をUTCに対して足しこむ事で対応する事とした。

date -d "9 hour"

blog.offline-net.com

sar(sysstat)のログ取得間隔が変更できない

事象

sarを10分間隔ではなく1分間隔で実行したい。
そのため、/etc/cron.d/sysstatを以下の様に書き換えた。

(変更前)
# Activity reports every 10 minutes everyday 
*/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1  

(変更後)
# Activity reports every 1 minutes everyday 
* * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1  

しかし、/var/log/sysstat配下のsarファイルを確認したが、取得間隔は10分のままであった。

原因

  • cronで取得せずにserviceで取得していたから
  • 再起動するserviceを間違えていたから

対応方法

cronで取得せずにserviceで取得していた

過去の歴史においてはsysstatはcronで実行していた。
しかし、現代社会においてはsysstat.serviceなるものが用意されている模様である。
tech-lab.sios.jp

なお、いくつか変更方法が各種サイトで紹介されている。
正式な方法としては、systemctl editで変えた方が良さそう。
https://www.ibm.com/docs/en/linuxonibm/pdf/Monitoring-with-RHEL-8-and-KVM.pdf
(See. 3.2 - Sysstat - Change Logging Interval)

なお、sysstatをserviceで起動している状態でcronを実行しても無視されていた。
そのため、/etc/cron.d/sysstatは削除した。

再起動するserviceを間違えていた

sysstatではなくsysstat-collect.timerを再起動しないといけない。
そのため、systemctl restart sysstat-collect.timerを行わなければならない。
但し、この方法はsystemctl editで変更した場合は関係ない。(※1)
もしくは、systemctl daemon-reloadのみでも反映されるかもしれない。(※2)

※1 削除の時を除き、即時反映されるはずなので
※2 おまじないの様にdaemon-reloadやsystemctl restartは投入してしまう

その他

systemctl edit の保存方法が分からない

デフォルトではnanoというエディタが起動する。
[ぱっと知りたい内容]

  • 保存はCtrl + o
  • 終了はCtrl + x
  • ^はCtrl、MはEscのこと

[詳細知りたい場合]
www.webdesignleaves.com

なお、vimなどに変更する方法もある模様
systemctl edit で起動するエディターを変える [まにまに.cc]