今回はSambaサーバーのセキュリティ設定で色々と苦労した点についてまた将来再構築したり障害復旧させてりするときのためにまとめておこうと思う。
個別の項目は都度調べればなんとでもなるんだけど、セキュリティの全体像が分からないとアクセス不可の原因を切り分けるのも難しいので図を描いてポイントを記録しておこうと思う。
1. Samba Shared Folder Access Control
注) Samba Shared Folder Access Controlという名前は他の制御と比べて自分が分かりやすいようにそう呼んでるだけなので一般的な呼称でないことに注意。
/etc/samba/smb.confの設定はこんな感じ。
[global] dos charset = CP932 unix charset = UTF-8 workgroup = WORKGROUP security = user interfaces = {ここにサーバーIP} 127.0.0.1 bind interfaces only = yes socket address = {ここにネットワークアドレス} printcap name = /dev/null log level = 1 [Share] path = /mnt/encrypted/Share writeable = yes [Archive] path = /mnt/encrypted/Archive writeable = no
ポイントはセクション名になっている[Share]や[Archive]がWindowsからみたときの共有名で、実際のpathのフォルダ名と同じでなくても良いということ。
セクションをコピペしてpathだけ変えてできたつもりになってたり、逆にセクション名だけ変えてpathの編集忘れというミスに注意。
設定を変更した場合はサービスを再起動して反映させる。
sudo systemctl restart smb.service
2. Samba Server
今回構築したサーバーでは以下記事のとおり暗号化RAIDを使用しているのでsmb.serviceの自動起動のタイミングでハマった。
thom.hateblo.jp
/mnt/encryptedのマウントが完了する前にsmb.serviceが自動起動してしまってsambaがエラーでフォルダアクセスできない。
簡易的な対処としてして自動起動ではなくrootユーザーのcrontabで起動させるようにした。
以下、smb.serviceの自動起動を無効化するコマンド。
sudo systemctl disable smb.service
以下はrootのcrontabに記述する内容。sudo suでrootになってからcrontab -eで編集した。
@reboot systemctl start smb.service
3. SE Linux
最近のLinuxではOSのファイル・フォルダーアクセス制御とは別にSE Linuxというセキュリティ強化機能が最初から導入され有効になっているケースが多い。
getenforceコマンドでステータスを確認でき、Enforcingと表示されたら有効になっている。
SE Linuxではどんなプロセスがどういうファイル・フォルダーにアクセス可能であるかをルール化しておくことができ、ルールに無いアクセスは却下される。
ルールに追記するのが本来のやり方だけど、フォルダーごとに手動でsamba_share_tタグをつけていく方法もある。(以下コマンド)
sudo chcon -t samba_share_t /mnt/encrypted/Archive
タグが付いたかどうかはls -Zコマンドで表示できる。
[thom@storage encrypted]$ ls -Z unconfined_u:object_r:samba_share_t:s0 Archive unconfined_u:object_r:samba_share_t:s0 Share
今回ハマった点としては暗号化処理で一時的にファイルの通り道となるsys_tmpフォルダーにsamba_share_tをつけ忘れたことで、sys_tmpで生成されたファイルを共有フォルダーに移してもWindows側から見えなくなったこと。
生成されたファイルは移動させる場合でも基本的には元親フォルダ―のタグを引き継いだままなのでSE Linuxによってsambaからのアクセスが拒否されているというのがWindowsで確認できない原因だった。
4. Linux Folder Access Control
注) Linux Folder Access Controlという名前は他の制御と比べて自分が分かりやすいようにそう呼んでるだけなので一般的な呼称でないことに注意。
ここでは曖昧な理解になりがちなファイルとフォルダーのアクセス権の関係性について説明しようと思う。
※一般的なAccess Controlの話(read/write/executeとowner/group/other)はLinux使ってたら耳タコなのであえて割愛。
特に分かりづらいのがとあるファイルやフォルダーが削除できるか・編集できるかという点である。
下図ではペンのアイコンに斜線が入ったものが書き込み不可に設定してあるとする。
上記の設定においてそれぞれのファイル・フォルダーに実際に行える操作は次のとおりである。
例えば、ファイルEは書き込み可能なのに削除できない、ファイルGは編集できないのに削除はできるというのは仕組みを知らないと直感に反しているように感じるかもしれない。原理としてはファイルやフォルダーの書き込み可否は、あくまでその中身についての話なので、そのファイル・フォルダー自体を消せるかどうかは常に親フォルダーが握っているということ。
Sambaの設定をする際にも特定フォルダーはrootにオーナーシップを持たせておいて中のフォルダー構成を勝手にいじれないようにしつつ、その子フォルダーにSambaによる書き込み権限を与えるといったやり方で制御することがあるのでOSアクセス権の基本は抑えておきたい。
5. Linux Firewall
最近のLinuxではファイアウォールポートが必要最小限のポート意外は閉じているようで、個別にオープンさせる必要がある。
Sambaを使うには445ポートが空いていればOK。
[thom@storage ~]$ sudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eno1 sources: services: cockpit dhcpv6-client ssh ports: 445/tcp protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
6. Network Firewall
ここは大手企業ならNW担当の領域なので特にサーバー管理で躓く場所ではないし、自宅やワンマンIT担当なら自分で設定してるはずなので原因の一つになりえるということを念頭に置きさえすれば、特に改めて説明することはない。
自宅のNW-FWはCisco CBS250の簡易ACLでネットワーク間のトラフィックを制御しているのみで、ポート単位での細かい制御はしてないので特に引っかかることは無かった。
7. Windows Firewall
自分から始めた通信に対する戻りのトラフィックはデフォルトで許可されているはずなので、特に追加設定してなければ引っかかることはないはず。
どこが悪いのかの切り分け
初期設定でうまくいかないときはサーバーにデータが入る前なので一時的にSE LinuxやLinux Firewallをストップして通信がうまくいくか確かめてみる。一旦ごっそり設定を解除してまずは通信を成功させ、それから通信ができなくなるまで一つずつ有効にしていき原因を探る。原因が分かったらきちんと調べて適切な設定をすることが重要。使えるからまるっと無効のままでいいやっていうのはセキュリティ的に非常にまずい。
その他
実際はデータ保管機能だけじゃなくて一時ファイルの自動削除スクリプトとか、永久アーカイブ対象ファイルを暗号化してAWSのS3バケットに保管する機能だったりを作っている。
AWS連携は以前書いた記事があるので詳しくは割愛。
thom.hateblo.jp
暗号化の仕組み等は別途書いてる記事がある。
thom.hateblo.jp
フォルダー構成は色々と悩んだ結果こうなった。アーカイブの分類とかもう少し凝った構成で計画をXにポストしてたけど結局アーカイブ本来の目的を考えると保管じゃなくて保存だから旧サーバー同様に分類しない投げ込み式を踏襲。
アーカイブ・暗号化・AWS連携・一時ファイルの自動削除を実現する実際のbashスクリプトは以下をcronで1分毎に動かしている。
#!/bin/bash FILES="/mnt/encrypted/ToArchive/*" TIMESTAMP=`date +'%Y%m%d%H%M%S'` PASSWORD="非公開情報のため削除" #file existence check for source folder if [ -n "$(ls -A /mnt/encrypted/ToArchive/)" ];then for f in $FILES do #duplicated file existence check for destination folder if [ ! -e /mnt/encrypted/Archive/$(basename -- $f) ]; then gzip -c $f | openssl enc -e -aes-256-cbc -pbkdf2 -iter 99999 -salt -k $PASSWORD -out /mnt/encrypted/sys_tmp/$(basename -- $f).gz.aes encf=/mnt/encrypted/sys_tmp/$(basename -- $f).gz.aes hfname=/mnt/encrypted/sys_tmp/`sha256sum -- $encf | awk '{print $1}'`.gz.aes mv $encf $hfname /usr/local/bin/aws s3 cp $hfname s3://非公開情報のため削除/ --profile 非公開情報のため削除 mv $hfname /mnt/encrypted/ToBeArchivedInMedia/ mv $f /mnt/encrypted/Archive/ echo $TIMESTAMP $(basename -- $f) $(basename -- $hfname) >> /mnt/encrypted/Archive/Index.txt else if [ ! -d /mnt/encrypted/ArchiveError/$TIMESTAMP ]; then mkdir /mnt/encrypted/ArchiveError/$TIMESTAMP fi mv $f /mnt/encrypted/ArchiveError/$TIMESTAMP fi done else : fi find /mnt/encrypted/Temp/10_minutes -type f -amin +10 -exec rm {} \; find /mnt/encrypted/Temp/24_hours -type f -atime +1 -exec rm {} \; find /mnt/encrypted/Temp/30_days -type f -atime +30 -exec rm {} \;
前回のサーバーとしてもうひとつ進化した点はファイル名の匿名化が挙げられる。
これによって万が一AWS S3やメディアバックアップが流出しても、中身はもちろんそのタイトルすら読めないので他人には内容の類推すらできないという安全なものになった。
機能刷新でハマったところ
まず久々に触るのでBashが読めない。特に$(basename -- $f)の部分が、調べ直した先の参考サイトと記載違っており、なんで前回「--」を書いたのか、何の意味があるのか全く分からずに半日を費やした。
答えはこちらにあった。
zenn.dev
Linuxのコマンドは「コマンド 複数のオプション 引数」という構成になってて、「--」はここでオプション終わりですよと明示する書き方らしい。それが無いと例えば今回のケースだと$fに入ってくるファイル名にスペースが入ってた場合、そこで区切った前半の内容がオプションと一致するとまずい。。。。そんなことあるか?まぁ一応ダブルダッシュはいれとこう。
次に現行機種で動いている暗号化スクリプトをそのまま採用すると警告が出るのでハマった。
オプションに-pbkdf2 -iter 99999を追加したらエラーは解決したんだけど、なんで旧サバで入れてないんだ?と思ったらOSが古くてOpen SSLのバージョンがそのオプションが登場する前のものしかリポジトリになかったのが原因だった。
新旧暗号化オプションが混じると復号化の方法が分かれてしまうため、今回は新オプションで過去のアーカイブも暗号化しなおしてAWSにアップロードしなおした。どのみちファイル名匿名化でアップロードし直したかったのでちょうどよかった。
最後にどうしても分からなかったのが、共有フォルダー配下のフォルダーの削除操作を拒否する方法。
次のような不可解な現象に悩まされて海外掲示板等も読み漁ったけど解決していない。
実用上は特に困ってないのでひとまずはそのまま運用することにした。
おわり
おわり。