Linuxの基礎試験「LinuC レベル1」に挑戦しながら学んだことをざっくりメモ

動作確認環境: Debian GNU/Linux 10 (buster)

useraddコマンド

ユーザを追加するコマンド。例えば以下のコマンドでホームディレクトリがとデフォルトシェルを指定できる

# ホームディレクトリ:/home/planet
# デフォルトシェル:/bin/bash
# ユーザ名:pluto
useradd -d /home/planet -s /bin/bash pluto

# 以下でユーザの一覧を表示できる
cat /etc/passwd

# 実行結果:pluto:x:1002:1002::/home/planet:/bin/bash

getentコマンドとshadow

  • getentコマンド:データベースを参照するコマンド
  • shadow:アカウント情報が書いてあるデータベース。/etc/shadowファイルに記録されている
# ユーザ名「pluto」についての情報をshadowからひっぱってくる
getent shadow pluto

# 実行結果:pluto:!:18509:0:99999:7:::
# 2列目はパスワード. 「!」はまだパスワードが設定されていないことを示しているっぽい?

passwdコマンド

パスワードを設定するコマンド.

# plutoのパスワードを設定
passwd pluto

# 実行すると以下が表示され、入力が求められる
# New password:
# Retype new password:

# パスワードを設定すると以下が表示
# passwd: password updated successfully

# ユーザのパスワードを確認してみると...
getent shadow pluto

# 実行結果:
# pluto:$6$XHF9AAh1Ro/h9ulA$nLeF9T3tPTXwkUuCwE6bji2qfhSTvI46EyxnmCfi8cSCm9xSwn5XQJ4aZLIuO9k78fftLdf3YWj5JdWQqeKRO.:18509:0:99999:7:::
#        ▲ さっきは「!」だった列が文字列に変わった(パスワードは「hoge」で設定した)

groups, groupadd, usermodコマンド

# ユーザ「pluto」が所属するグループを確認
groups pluto

# 実行結果:
# pluto : pluto
# ▲ユーザ名 ▲グループ名

## ---- plutoのグループを変えたい! ----
## ---- まず、今あるグループを確認したい ----

# グループ一覧を確認
cat /etc/group

# 実行結果:
# planets:x:1001:
# pluto:x:1002:

## ---- planetsしかない(冥王星は準惑星だしplanetsには入れられないよな....) ----
## ---- 準惑星グループ作ろう(準惑星:dwarf planet) ----

# グループ追加(準惑星)
groupadd dwarf_planet

# グループ一覧再確認
cat /etc/group

# 実行結果:
# planets:x:1001:
# pluto:x:1002:
# dwarf_planet:x:1003:
#                 ▲ GID. 明示的に指定するならgroupaddにgオプション使う

## ---- 無事、準惑星グループが出来たのでplutoユーザを加えよう ----

# ユーザ「pluto」のグループを準惑星に変更
usermod -G dwarf_planet pluto

# グループ再確認すると...
groups pluto

# 実行結果:
# pluto : pluto dwarf_planet
#           ▲ plutoにもまだ所属している?

# ▲ これは「usermod -Gオプション」は「セカンダリーグループ」を追加するコマンドだから。
# 「プライマリーグループ」を「変更する」なら「-gオプション」で指定する
usermod -g dwarf_planet pluto

userdelコマンド

ユーザの削除を行う.

# ユーザ削除(ホームディレクトリは削除しない)
userdel pluto

# ユーザ削除(ホームディレクトリを削除する)
userdel -r pluto

/etc/skelディレクトリ

ここにファイルを置くと、新規ユーザ作成時にそのユーザのホームディレクトリに自動配置される

cron

定期実行したいときにはcronを使う. どんな内容をどんな頻度で実行するかは「crontab -e」で編集できる

# 定期実行の内容を書く
crontab -e

# ---- 起動した編集画面で以下を入力 ----
# 「1分ごとにdateコマンドを実行してhoge.logに書き込む」よう指示(誰得)
# */1 * * * * date >> /home/hoge.log
# ---- 上記は「分 時 日 月 曜日 コマンド」の意味合い. ----

# service crond start でcron開始できるっぽい、
# けど出来なかったので以下で起動した
sudo /etc/init.d/cron restart

タイムゾーンの変更

# 現在はUTC協定世界時
date
# 実行結果:Sat Sep  5 01:23:43 UTC 2020

# まず、今設定されているlocaltimeを削除する
rm /etc/localtime

# 新しく設定したいタイムゾーンのシンボリックリンクを/etc/localtimeとして配置する
ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# 再確認
date
# 実行結果:Sat Sep  5 10:24:02 JST 2020

# 無事に日本時間に設定された!

# ---- ちなみに、シンボリックリンクが見てる先を確認するならこう ----
ls -l /etc/localtime

# 実行結果:
# lrwxrwxrwx 1 root root 30 Sep  5 10:23 /etc/localtime -> /usr/share/zoneinfo/Asia/Tokyo

rsyslog

Linuxの多くのディストリビューションで採用されているシステムログを司るソフトウェア. /etc/rsyslog.confの設定内容に従いログを出力する。

# rsyslogの設定を確認
cat /etc/rsyslog.conf

# __________________________________________________________________
# 以下、rsyslogの設定ファイルの内容
# -------------------------------

# /etc/rsyslog.conf configuration file for rsyslog
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html


#################
#### MODULES ####
#################

# loggingコマンドなどUNIXソケットによるログ機能の読み込み
module(load="imuxsock") # provides support for local system logging
# カーネルログ機能の読み込み
module(load="imklog")   # provides kernel logging support
# マークを出力する機能の読み込み
module(load="immark")  # provides --MARK-- message capability

# UDP経由でログを受け取る機能の読み込み
module(load="imudp")
# 入力ソースの指定
input(type="imudp" port="514")

# TCP経由でログを受け取る機能の読み込み
module(load="imtcp")
# 入力ソースの指定
input(type="imtcp" port="514")


###########################
#### GLOBAL DIRECTIVES ####
###########################


# フォーマットの指定
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# パーミッションの設定
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022

# 作業ディレクトリの指定
$WorkDirectory /var/spool/rsyslog

# その他の設定ファイルの読み込み
$IncludeConfig /etc/rsyslog.d/*.conf


###############
#### RULES ####
###############

# 【ファシリティ】.【プライオリティ】 【出力先】を指定
#  ・ファシリティ:メッセージの生成元
#  ・プライオリティ:メッセージの重要度
#   ・低いものから順にnone, debug, info, notice, warning, err, crit, alert, emergがある
#  ・出力先:以下のような書き方がある
    ・/var/log/hoge.log:指定したファイルにログ書き出し
    ・-/var/log/hoge.log:同期を省略して書き出し
    ・/dev/tty1:tty1のコンソールに出力
    ・@hoge.com:514:ホストhoge.comにUDPでログ送信(※UDP:コネクションレス)
    ・@@hoge.com:514:ホストhoge.comにTCPでログ送信(※TCP:コネクションを確立して通信)

# ログインなど認証システムのルール
auth,authpriv.*                 /var/log/auth.log
# システムログのルール
*.*;auth,authpriv.none          -/var/log/syslog
# cronのルール
cron.*                          /var/log/cron.log
# デーモン関連のルール
daemon.*                        -/var/log/daemon.log
# カーネルのルール
kern.*                          -/var/log/kern.log
# プリンターのルール
lpr.*                           -/var/log/lpr.log
# メールのルール
mail.*                          -/var/log/mail.log
# ユーザアプリのルール
user.*                          -/var/log/user.log

# ※そのほか「local0~local7」のローカルシステムのファシリティもある

# プライオリティごとに出力先を分けることも可能
mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err


# ---- 以下記法で「~を除くすべて」のルールを書ける ----

# 「認証, ニュース, メール」以外の全てのdebugログ
*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug

# 「認証, cron, デーモン, メール, ニュース」以外の全てのinfoログ
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

# emergログは「全ユーザ」に出力
# ※【omusrmsg】は「Output Module User Massage」の略?
#  とりあえず、ログイン中のユーザのコンソールにメッセージを出力するモジュールっぽい
*.emerg                         :omusrmsg:*

rsyslog.confの設定を書き換えて、rsyslogを再スタートしたいときは以下のように書く。

systemctl restart rsyslog

# 上記ができないなら以下
 /etc/init.d/rsyslog restart

loggerコマンド

# pオプション:ファシリティとプライオリティ
# tオプション:タグ
logger -p syslog.info -t TEST "hoge"

# 実行結果の確認
cat /var/log/syslog
# 実行結果:Sep  6 11:17:51 e16648fc2996 TEST: hoge

systemd-catコマンド

# 以下でジャーナルにコマンドの実行結果を書き込みできる
systemd-cat 【コマンド】

# ジャーナルの確認
journalctl -xe

grepコマンド

grep 【探索する文字列】 【探索する対象ファイル】

apt-getコマンド

# hogeパッケージの削除(設定ファイルは残る)
apt-get remove hoge

# hogeパッケージの削除(設定ファイルごと消す)
apt-get purge hoge

mailコマンド

# mail送信
echo "hoge" | mail -s subject user

# mail確認
mail

# 未送信のメール確認
mailq

# メールアドレスのエイリアス設定の確認
cat /etc/aliases

# ---- 設定内容の意味 ----
# # nobody宛てのメールをroot宛てに転送(rootには届かなくなる)
# nobody: root
# 
# # 複数人に転送ならこう(news宛てのメールをrootとuser1に転送)
# news: root, user1

# /etc/aliasesの内容をもとにMTAが参照するエイリアスデータベース(/etc/aliases.db?)を更新
newaliases


# ほかにも「.forward」ファイルで転送も可能
# この場合、.forwardは各ユーザの$HOMEに配置する

SUID, SGID, スティッキービット

  • SUID:Set User IDの意味. 他のユーザが実行したときでも、ファイル所有者の権限でファイルが実行される. パーミッションの数値は4000
  • SGID:Set Group IDの意味. SUIDのグループ版. パーミッションの数値は2000
  • スティッキービット:その他のユーザの実行権限のひとつ。「書き込みはできるが、削除はできない」という状態. パーミッションの数値は1000
# たとえば「passwd」コマンドはrootしか書き込み権限のないはずの/etc/shadowの書き込みができる.
# passwdのパーミッションを確認してみると...
ls -l /usr/bin/passwd

# 実行結果(所有者の権限に「s」がある = SUIDが付与されている)
-rwsr-xr-x 1 root root 63736 Jul 27  2018 /usr/bin/passwd

# 上記パーミッションを数値で確認してみると...
stat /usr/bin/passwd -c  '%a'

# 実行結果:4755
# ▲ SUIDは「4000」
#  ※なお、SGIDは「2000」. スティッキービットは「1000」

#______________________________________________________________

# セキュリティの観点からSUIDが付与されたファイルを調べたいときは以下を実行
find / -perm -u+s -ls

# SGID探すなら以下
find / -perm -g+s -ls

# スティッキービット探すなら以下
find / -perm -o+t -ls

chageコマンド

パスワードの有効期限などを設定する.

# ユーザ「sigsig」のパスワードの有効期限を対話モードで変更する
chage sigsig

# ---- 以下対話モードの出力と入力 ----
Changing the aging information for sigsig
Enter the new value, or press ENTER for the default
        # パスワードを変更するには最低でも「x日」空けないといけない
        # -mオプションで指定可
        Minimum Password Age [0]: 1

        # パスワードの最大有効期限
        # -Mオプションで指定可
        Maximum Password Age [99999]: 300

        # 最後にパスワードを変更した日付
        # -dオプションで指定可
        Last Password Change (YYYY-MM-DD) [2020-09-05]:

        # パスワードが切れる「x日」前に警告表示
        # -Wオプションで指定可
        Password Expiration Warning [7]:

        # パスワードが無効になった日から「x日」でアカウント停止 ※「-1」はアカウント停止無効
        # -Iオプションで指定可
        Password Inactive [-1]:

        # アカウントの有効期限 ※「-1」は有効期限無効
        # -Eオプションで指定可
        Account Expiration Date (YYYY-MM-DD) [-1]:

who, w, lastコマンド

/var/run/utmpの情報を参照するコマンド。/var/run/utmpにはログイン中のユーザに関する情報が書かれている

who
# user1 pts/1      2020-09-07 07:57 (192.168.1.41)

w
# 08:34:28 up 1 day, 13:22,  1 users,  load average: 0.10, 0.09, 0.024
# USER     TTY      FROM             [email protected]   IDLE   JCPU   PCPU WHAT
# user1    pts/1    192.168.1.41     07:57    0.00s  0.00s  0.00s w

開いているポートの確認など

以下のコマンドで確認できる

  • netstat -atu
  • ss -atu
  • lsof -i
  • nmap

またポートを開いているプロセスを確認するなら「fuserコマンド + nオプション」を使う.

netstat -atu
# Active Internet connections (servers and established)
# Proto Recv-Q Send-Q Local Address           Foreign Address         State
# tcp        0      0 0.0.0.0:shell           0.0.0.0:*               LISTEN
# tcp        0      0 e16648fc2996:46790      151.101.108.204:http    TIME_WAIT
# tcp6       0      0 [::]:shell              [::]:*                  LISTEN
# udp        0      0 0.0.0.0:syslog          0.0.0.0:*
# udp6       0      0 [::]:syslog             [::]:*

ss -atu
# Netid           State            Recv-Q            Send-Q                       Local Address:Port                         Peer Address:Port
# udp             UNCONN           0                 0                                  0.0.0.0:syslog                            0.0.0.0:*
# udp             UNCONN           0                 0                                     [::]:syslog                               [::]:*
# tcp             LISTEN           0                 25                                 0.0.0.0:shell                             0.0.0.0:*
# tcp             LISTEN           0                 25                                    [::]:shell                                [::]:*

lsof -i
# COMMAND   PID  USER    FD   TYPE DEVICE SIZE/OFF NODE NAME
# java    16000 user1    17u  IPv6 9473        0t0  TCP *:8080 (LISTEN) 

nmap localhost
# Starting Nmap 7.70 ( https://nmap.org ) at 2020-09-07 08:56 JST
# Nmap scan report for localhost (127.0.0.1)
# Host is up (0.000011s latency).
# Other addresses for localhost (not scanned): ::1
# Not shown: 999 closed ports
# PORT    STATE SERVICE
# 514/tcp open  shell
# 
# Nmap done: 1 IP address (1 host up) scanned in 1.85 seconds

fuser -n tco 8080
# 8080/tcp: 15858

ユーザのログインまわりのセキュリティ対策

「アカウントは必要だけど、ログインはできないようにしたい」というときにはデフォルトシェルを変更するとOK

# 方法1
usermod -s /bin/false user1

# 方法2
usermod -s /sbin/nologin user1

ほかにもセキュリティ対策として、「一定時間操作がないときに自動ログアウトさせたい」ときには環境変数「TMOUT」を書き換えるとOK

# 設定値は秒数
export TMOUt=600

その他のセキュリティ対策

  • システムリソースの制限:ulimitコマンドを使う
  • 一時的なユーザ変更:suコマンド.
    • 【su user1】:環境の変化なし
    • 【su – user1】:ログインしたときと同じように環境が変化する(今いるディレクトリがそのユーザのホームディレクトリになる
  • 特定のコマンドのみroot:sudo(後述)

sudoコマンド

/etc/sudoersファイルの設定内容に従い、特定の管理者コマンドを一般ユーザができるようにするコマンド. sudoersファイルを書き換えるにはvisudoコマンドが使える.

visudoコマンドではなく/etc/sudoersファイルを直接書き換えることもできるが、visudoコマンドなら文法誤りをチェックする機能があるので、visudoでの書き換えが推奨.

# ユーザ名  ホスト名=実行ユーザ名 コマンド
root       ALL=(ALL:ALL) ALL

# 「%グループ名」でグループ単位の設定もできる
%sudo   ALL=(ALL:ALL) ALL

# 上記のほか、「NOPASSWD:」でパスワード不問にできる

また、sudoコマンド実行時にはパスワードが求められるが、このときのパスワードは「rootユーザのパスワード」ではなく、「現在ログインしているユーザのパスワード」であることに注意。

なお、自分が許可されているコマンドを調べたいときは、「lオプション」で確認できる

sudo -l

fdiskコマンド

パーティションを操作するコマンド.

sudo fdisk /dev/sdb

# 以下 実行結果(コマンド一覧を見たかったので、対話モード上で「mコマンド」を入力した)
# -------------------

# Welcome to fdisk (util-linux 2.34).
# Changes will remain in memory only, until you decide to write them.
# Be careful before using the write command.
# 
# The old ext4 signature will be removed by a write command.
# 
# Device does not contain a recognized partition table.
# Created a new DOS disklabel with disk identifier 0x732dcfd9.
# 
# Command (m for help): m
# 
# Help:
# 
#   DOS (MBR)
#    a   toggle a bootable flag
#    b   edit nested BSD disklabel
#    c   toggle the dos compatibility flag
# 
#   Generic
#    d   delete a partition
#    F   list free unpartitioned space
#    l   list known partition types
#    n   add a new partition
#    p   print the partition table
#    t   change a partition type
#    v   verify the partition table
#    i   print information about a partition
# 
#   Misc
#    m   print this menu
#    u   change display/entry units
#    x   extra functionality (experts only)
# 
#   Script
#    I   load disk layout from sfdisk script file
#    O   dump disk layout to sfdisk script file
# 
#   Save & Exit
#    w   write table to disk and exit
#    q   quit without saving changes
# 
#   Create a new label
#    g   create a new empty GPT partition table
#    G   create a new empty SGI (IRIX) partition table
#    o   create a new empty DOS partition table
#    s   create a new empty Sun partition table
# 

このほかGUIDパーティションテーブル(GPT)に対応したgdiskコマンドもある.

※ 参考:パーティションテーブルの方式

  • MBR(マスターブートレコード):fdiskコマンドで管理
  • GPT(GUIDパーティションテーブル):gdiskコマンドで管理
  • 上記2方式に対応:partedコマンド