Memo

メモ > サーバ > 構築: 攻撃からの防御

■TCP Wrapperでアクセス制限
※httpに対しては使えないので注意。httpの場合は .htaccess で制限する ※127.0.0.1からのアクセスは許可しておく
# vi /etc/hosts.deny
#FTPへのアクセスを拒否 vsftpd: all
# vi /etc/hosts.allow
#アクセスを許可 vsftpd: 127.0.0.1 vsftpd: 203.0.113.0
■設定例
# vi /etc/hosts.deny
#SSHへのアクセスを拒否 sshd: all #不正アクセスを拒否 all: (IPアドレス) all: (IPアドレス)
# vi /etc/hosts.allow
#ローカルからのアクセスを許可 sshd: 127.0.0.1 #自宅からのアクセスを許可 sshd: 203.0.113.0 #会社からのアクセスを許可 sshd: 203.0.113.1
少なくともCentOS系では、httpdに対しては使えないので注意 環境によってはhttpdに対しても使えることがあるみたい SSH接続をIPアドレスで制限する - Qiita https://qiita.com/wwwaltz/items/db774fda77cb2d6c6922
■.htaccess でアクセス制限
※.htaccessとは、Webサーバーの基本的な動作をディレクトリ単位で制御するためのファイル Apacheで利用できるが、nginxでは対応していないので注意 ※複数を設定するとき、設定順に注意 例えば「Order Deny,Allow」とした場合は「Deny → Allow」の順に設定する必要がある。混在させると正しく動作しない ※行の途中に「#」を書いてコメントを設けると、Apacheのバージョンによってはエラーになる 行頭から「#」を書いてコメントを設けるのが無難 ■特定IPからのみアクセスを許可
Order Deny,Allow Deny from all Allow from 203.0.113.1 Allow from 203.0.113.2
■特定IPからのアクセスを拒否
Order Allow,Deny Allow from all Deny from 203.0.113.1 Deny from 203.0.113.2
■特定IPからのアクセスを拒否(ロードバランサーを考慮)
SetEnvIf X-Forwarded-For "203.0.113.1" deny_ip SetEnvIf X-Forwarded-For "203.0.113.2" deny_ip Order Allow,Deny Allow from all Deny from env=deny_ip
Nginx と Apache の、Basic認証 と IP制限 の様々な設定方法まとめ (ELBの有無も考慮) #nginx - Qiita https://qiita.com/hirai-11/items/c76b6890a65866905663 ■特定IPからのアクセスを拒否(直接アクセスとロードバランサーの両方を考慮)
SetEnvIf X-Forwarded-For "203.0.113.1" deny_ip SetEnvIf X-Forwarded-For "203.0.113.2" deny_ip Order Allow,Deny Allow from all Deny from 203.0.113.1 Deny from 203.0.113.2 Deny from env=deny_ip
■特定範囲IPからのアクセスを拒否 ※「203.0.113.0」と「10.0.0.0 〜 10.255.255.255」からのアクセスを許可
Order Allow,Deny Allow from all Deny from 203.0.113.0 Deny from 10.
■特定範囲IPからのアクセスを拒否(mod_rewriteでの指定) ※未検証 上にあるように「10.」のような書き方は有効か、なども確認したい apacheのRewriteCondをサブネットマスクで許可する - helen's blog https://helen.hatenablog.com/entry/2017/03/01/173847 IPアドレスとサブネットマスクとRewriteCond - knowledge::short https://www.km92.net/knowledge_short/2018/180222_000238.html .htaccessで特定のIPアドレス以外をメンテナンスページへ302リダイレクトさせてみた | www.ni4.jp https://www.ni4.jp/2018/02/17-220835.html
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_URI} ^.*/news/admin.*$ [OR] RewriteCond %{REQUEST_URI} ^.*/news/index\.php/admin.*$ # IPアドレス直接指定 RewriteCond %{REMOTE_ADDR} !=203.0.113.1 RewriteCond %{REMOTE_ADDR} !=203.0.113.2 # IPアドレス範囲指定 #RewriteCond %{REMOTE_ADDR} !=192.168.33.0/25 … この書き方は無効 RewriteCond %{REMOTE_ADDR} !^(192\.168\.33\.([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-6])$) … 正規表現で指定する必要がある RewriteRule ^(.*)$ - [F,L] </IfModule>
■特定ブラウザからのアクセスを拒否
BrowserMatch "Chrome/62.0.3202.94" bad_bot Order Allow,Deny Allow from all Deny from env=bad_bot
■特定ツールからのアクセスを拒否
BrowserMatch "Wget/1.14 (linux-gnu)" bad_bot Order Allow,Deny Allow from all Deny from env=bad_bot
■その他参考ページ 【基本】.htaccessとは?何ができるの?書き方は? | カゴヤのサーバー研究室 https://www.kagoya.jp/howto/it-glossary/web/htaccess/ .htaccess の書き方 | murashun.jp https://murashun.jp/article/programming/htaccess/htaccess-writing.html ELB配下のApacheでのアクセス制御 | Developers.IO http://dev.classmethod.jp/cloud/aws/access-limit-behind-elb/ X-Forwarded-Forを使用して、IPアドレスでのアクセス制限 | ゆっくりと歩んでいこう https://ymyk.wordpress.com/2010/02/25/x-forwarded-for%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E... nginxでは .htaccess に対応していない nginxに.htaccessを移行する。 - Qiita https://qiita.com/rdonster/items/a49b1861003645e7054b Nginxなはずのエックスサーバーで.htaccessが有効な理由 | アフィ+さぽ! https://affi-sapo.com/1264/ htaccessを使わない方が良いとApacheとNginxの公式が言っている - suzu6の技術ブログ https://www.suzu6.net/posts/240-htaccess-apache-vs-nginx/ 【基本】.htaccessとは?何ができるの?書き方は? | カゴヤのサーバー研究室 https://www.kagoya.jp/howto/it-glossary/web/htaccess/
■Basic認証でアクセス制限
■Apache ユーザ名「test」、パスワード「1234」で制限をかける例
# vi .htaccess
AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/html/secret/.htpasswd Require valid-user
# vi .htpasswd
test:ZM56IZdqDMwjY
Basic認証設定ツール | refirio.org http://refirio.org/view/368 htpasswdファイル生成(作成) http://www.luft.co.jp/cgi/htpasswd.php .htaccessファイルの利用が許可されていない場合、あらかじめ許可しておく必要がある 以下は /home/test 内で.htaccessの利用を許可する例(「AllowOverride All」を指定すると許可される)
# vi /etc/httpd/conf/httpd.conf
<Directory "/home/test"> AllowOverride All </Directory>
設定したら、Apacheの設定ファイルを再読み込みする
# service httpd reload
■Apache 2.4(特定のディレクトリ配下のみ) ※未検証 ディレクトリが存在する場合、そのディレクトリ直下に .htaccess を作成してBasic認証を設定すればいい 実際にはディレクトリが存在しない場合(URLルーティングを使用している場合など)、以下のように指定することで対応できる この場合、「/basic/secret」内にのみBasic認証をかけている
AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/html/example/html/basic/.htpasswd #Require valid-user SetEnvIf Request_URI '/basic/secret' secret <RequireAny> Require valid-user Require env secret </RequireAny>
特定のURLだけBasic認証を掛けない #Apache - Qiita https://qiita.com/SHIN_DEVELOP/items/1cb7845fbfcd4bba3d69 ■Apache 2.4(特定のディレクトリは除外) ※「.htaccess でアクセス制限」も参考に
AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/html/secret/.htpasswd Require valid-user SetEnvIf Request_URI "/upload/image/" isImage <RequireAny> Require env isImage Require valid-user </RequireAny>
■Apache 2.4(特定のユーザーエージェントは除外) ※「.htaccess でアクセス制限」も参考に
AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/html/secret/.htpasswd Require valid-user SetEnvIf User-Agent "Edg/89.0" isEdge SetEnvIf User-Agent "Selenium" isSelenium <RequireAny> Require env isEdge Require env isSelenium Require valid-user </RequireAny>
Apache 2.4 アクセス制御 - eastforest https://www.eastforest.jp/vps/4943 ■Apache 2.4(特定のIPアドレスは除外) ※「.htaccess でアクセス制限」も参考に
AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/html/secret/.htpasswd Require valid-user <RequireAny> Require ip 127.0.0.1 Require ip 203.0.113.1 Require valid-user </RequireAny>
Apache 2.4 アクセス制御 - eastforest https://www.eastforest.jp/vps/4943 MYN - 2016/05/30 14:21 / Apache 2.4.10 Satisfy Any http://myn.meganecco.org/1464585660.html 【.htaccess】特定のIPを除外してベーシック認証をかける方法 | web関連 | 勉強ブログ「二色人日記。」 https://twotone.me/web/3312/ ■Apache 2.2(特定のディレクトリ配下のみ) ディレクトリが存在する場合、そのディレクトリ直下に .htaccess を作成してBasic認証を設定すればいい 実際にはディレクトリが存在しない場合(URLルーティングを使用している場合など)、以下のように指定することで対応できる この場合、「/basic/secret」内にのみBasic認証をかけている
AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/html/example/html/basic/.htpasswd Require valid-user SetEnvIf Request_URI '^/basic/secret' secret Satisfy any Order Deny,Allow Deny from all Allow from env=!secret
【Wordpress】特定URLにマッチするときにベーシック認証をするよ! - やったこと https://absg.hatenablog.com/entry/2020/02/18/211922 ■Apache 2.2(特定のディレクトリは除外) ※「.htaccess でアクセス制限」も参考に Basic認証配下のディレクトリに、以下を記述した.htaccessを置くと、そのディレクトリをBasic認証対象外にできる
Satisfy any order allow,deny allow from all
.htaccessで特定のファイルやディレクトリのみBASIC認証を解除する | ザ サイベース https://thesaibase.com/server/htaccess-basic-auth ■Apache 2.2(特定のユーザーエージェントは除外) ※「.htaccess でアクセス制限」も参考に 以下のようにすれば、特定のユーザーエージェントからのみBasic認証なしでアクセスできる 以下は「Edg/89.0」もしくは「Selenium」を含むものを許可する例
Satisfy Any BrowserMatchNoCase Edg/89.0 isEdge=1 BrowserMatchNoCase Selenium isSelenium=1 Order Deny,Allow Deny from all Allow from env=isEdge Allow from env=isSelenium AuthUserFile /var/www/html/secret/.htpasswd AuthGroupFile /dev/null AuthName "Input ID and Password." AuthType Basic require valid-user <Files ~ "^.(htpasswd|htaccess)$"> deny from all </Files>
Apache で特定の User-Agent だけ BASIC 認証をバイパスする方法 - アクトインディ開発者ブログ https://tech.actindi.net/2010/05/14/3482790616 ■Apache 2.2(特定のIPアドレスは除外) ※「.htaccess でアクセス制限」も参考に 以下のようにすれば、特定のIPアドレスからのみBasic認証なしでアクセスできる 以下は「127.0.0.1」と「203.0.113.1」を許可する例
Satisfy Any Order Deny,Allow Deny from all Allow from 127.0.0.1 Allow from 203.0.113.1 AuthUserFile /var/www/html/secret/.htpasswd AuthGroupFile /dev/null AuthName "Input ID and Password." AuthType Basic require valid-user <Files ~ "^.(htpasswd|htaccess)$"> deny from all </Files>
■nginx .htaccessで設定することはできないので、nginxの設定ファイルを編集して再起動する 例えば nginx.conf で以下のように設定すると、「/secret/」がBasic認証の対象になる .htpasswd の内容はApacheと同じ要領で作成できる
server { listen 80 default_server; server_name _; index index.html; root /var/www/html; sendfile off; location / { } location ^~ /secret/ { auth_basic "Auth"; auth_basic_user_file /var/www/html/secret/.htpasswd; } }
以下で設定ファイルの文法チェックができる
# nginx -t -c /etc/nginx/nginx.conf
設定できたら以下のコマンドで設定ファイルを再読込する
# service nginx reload
再読込で大丈夫だが、もし反映されなければ再起動も試す
# service nginx restart
それでも駄目なら、いったん停止してから起動する
# service nginx stop # service nginx start
Nginx で Basic 認証 - Qiita https://qiita.com/kotarella1110/items/be76b17cdbe61ff7b5ca htpasswdファイル生成(作成) http://www.luft.co.jp/cgi/htpasswd.php nginxで設定ファイルチェック - Qiita https://qiita.com/yaotti/items/bd6774888a790c00e6fd Nginxでベーシック認証を行う際の注意点 http://wpnote.link/notes-when-performing-basic-authentication-with-nginx/ 上の手順でPHPページに対してBasic認証を設定すると、対象ページではPHPが実行されなくなる 冗長だが、以下のようにここにもPHPの設定を書く必要があるみたい
location ^~ /secret/ { auth_basic "Auth"; auth_basic_user_file /var/www/vhosts/test/public/tool/.htpasswd; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/vhosts/test/public$fastcgi_script_name; include fastcgi_params; } }
nginxだとphp scriptファイルにbasci認証がかからないんで すけどー - オレンジの国 http://technical.live-on.net/archives/1414 ただしLaravelなどURLルーティング機能のあるフレームワークを使っている場合、 /index.php がリクエストを受け取って処理を始めるため、上記の方法で個別にBasic認証を制御できないみたい それでも設定すると、フレームワークから /secret/ のURLを呼び出したときに404エラーとなってしまう 対処方法があるかは要調査 以下は可能性がありそう?未検証 NginxでBasic認証(Laravel) | Qrunch(クランチ) https://qrunch.net/@G8AaKC38xzUeSbBe/entries/u9XM60aUWnMgTkts ■nginx(特定のディレクトリは除外) 以下のようにすれば、「.well-known」ディレクトリ内には認証なしでアクセスできる
location / { try_files $uri /index.php?$query_string; auth_basic "Auth"; auth_basic_user_file /var/www/main/.htpasswd; location /.well-known/ { satisfy any; allow all; } }
[Nginx] 特定 URL を Basic 認証から除外する方法 | CodeNote https://codenote.net/nginx/4204.html ■nginx(特定のユーザーエージェントは除外) 以下のようにすれば、特定のユーザーエージェントからのみBasic認証なしでアクセスできる 以下は「Chrome-Lighthouse」もしくは「Selenium」を含むものを許可する例 (なお「Chrome-Lighthouse」を許可すると、Basic認証をかけたサイトでもPageSpeed Insightsでの計測ができる)
location / { auth_basic "Auth"; ↓ set $auth "Auth"; if ($http_user_agent ~ (Chrome-Lighthouse|Selenium)) { set $auth off; } location / { auth_basic $auth;
Nginxでbotからのアクセス時にBasic認証を外す #nginx - Qiita https://qiita.com/maruware/items/63574425900010a1b37a ■nginx(特定のIPアドレスは除外) 以下のようにすれば、特定のIPアドレスからのみBasic認証なしでアクセスできる 以下は「203.0.113.1」と「203.0.113.2」を許可する例
location / { satisfy any; allow 203.0.113.1; allow 203.0.113.2; deny all; auth_basic "Auth"; auth_basic_user_file /var/www/vhosts/test/.htpasswd; }
nginx 一部のアドレスにbasic認証を掛けない。 - podhmoの日記 http://d.hatena.ne.jp/podhmo/20110311/1299817584 nginxで特定のIPからは公開したいけどそれ以外はBASIC認証にしたいときの設定 - Qiita https://qiita.com/katamuki/items/9a0a5f288d041b421f4c ■AWS ALB+Lambda AWS.txt の「ロードバランサー」の「Basic認証」を参照 ■「AuthName」の値 上記で記載している「AuthName "Input ID and Password."」のような内容は正確では無さそう Apache | Basic認証を使ったアクセス制限を行う https://www.javadrive.jp/apache/allow/index3.html AuthNameの説明は 「認証領域」 「一度認証が通ったあと同じ認証領域の名前が設定されている Basic 認証が必要なページへアクセスしたときに認証が不要となります。」 とある よってここは「Developer」「Admin」「Sales」のような区分を設定すべきだと思われる ここの文字列が認証ダイアログに表示されるブラウザもあるが、少なくともChromeでは表示されない (「認証領域をユーザに告知する」という意味では、表示される方が自然な気はするが) よって何かしらの案内を書く場所でも無いのかもしれない ■.htpasswdの解析 htpasswdファイルに書かれたパスワードは非可逆な暗号化(ハッシュ化)されているため、復号化できない ただし入力したパスワードはBase64してヘッダ内に付与してやりとりされるため、ここからならパスワードを抜き出すことはできる つまりBasic認証の情報は暗号化されずに平文でやりとりされるため、SSL無しでBasic認証を使用するのは好ましくない 以下は具体例 とあるページで認証してからヘッダ情報を確認すると以下が記載されていた Authorization: Basic ZGVtbzplbnRyeQ== この「ZGVtbzplbnRyeQ==」をBase64デコードすると「demo:entry」となる これがBasic認証の認証情報 とあるページで認証してからヘッダ情報を確認すると以下が記載されていた authorization: Basic c3RhZ2luZzpxYXp3c3hlZGM= この「c3RhZ2luZzpxYXp3c3hlZGM=」をBase64デコードすると「staging:qazwsxedc」となる これがBasic認証の認証情報 .htpasswdファイルの解析(デコード)は無理。 | クズリーマンのカス備忘録 https://it-afi.com/apache/post-1054/
■ロードバランサーでアクセス制限
AWSでEC2+ELBを使っている場合、ロードバランサーでアクセス制限できる AWSのEC2+ELBで、ロードバランサへのアクセス時点で特定IPからのアクセスを弾く - Hina-Mode http://hinashiki.hateblo.jp/entry/2015/02/19/161258 ルール番号の若いものから優先的に判定されるので注意 222.175.107.74 からのアクセスを拒否する場合、一例だが以下のように設定する (他2つは、もともと設定されているもの) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ルール タイプ プロトコル ポート範囲 ソース 許可 / 拒否 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 50 すべてのトラフィック すべて すべて 222.175.107.74/32 拒否 100 すべてのトラフィック すべて すべて 0.0.0.0/0 許可 * すべてのトラフィック すべて すべて 0.0.0.0/0 拒否 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■ネットワークACLでアクセス制限
AWSを使っている場合、VPC全体にアクセス制限をかけることができる 詳細は AWS.txt の「ネットワークACL」を参照
■TCP Wrapperで Dynamic DNS からのアクセスを許可
# mkdir /etc/hosts.allow.d # vi /etc/crontab
00 * * * * root /usr/bin/host refirio.mydns.jp | awk '{print $4}' > /etc/hosts.allow.d/refirio_ip
# vi /etc/hosts.allow
#アクセスを許可 vsftpd: /etc/hosts.allow.d/refirio_ip
参考 : DynamicDNSを利用し、iptablesとhosts.allowのルールに自宅IPを自動で追加する http://blog.glidenote.com/blog/2011/12/28/dyndns-iptables-hosts.allow/
■iptableでアクセス制限
IPアドレスで制限
-A MY-FIREWALL -m state --state NEW -m tcp -p tcp --dport 21 -s 202.213.216.201 -j ACCEPT -A MY-FIREWALL -m state --state NEW -m tcp -p tcp --dport 60000:60030 -s 202.213.216.201 -j ACCEPT
ホスト名で制限
-A MY-FIREWALL -m state --state NEW -m tcp -p tcp --dport 21 -s www.example.com -j ACCEPT -A MY-FIREWALL -m state --state NEW -m tcp -p tcp --dport 60000:60030 -s www.example.com -j ACCEPT
■iptableのログ
iptablesの設定 http://www.nina.jp/server/redhat/iptables/iptables.html iptablesのログフォーマットと内容について http://tech.sayama-yuki.net/archives/422 /etc/sysconfig/iptables を編集する
#以上のチェックにかからなかったパケットは、ICMPパケット host-prohibited を返して接続を拒否 -A MY-FIREWALL -j REJECT --reject-with icmp-host-prohibited
この直前に以下を追加し、iptableを再起動
#以上のチェックにかからなかったパケットを /var/log/messages に記録。ただし記録は1秒間に1回まで -A MY-FIREWALL -j LOG --log-level info --log-prefix "[IPTABLES REJECT]: " -m limit --limit 1/s
/var/log/messages に以下のようなログが記録されるようになった
Mar 21 16:02:05 refirio kernel: [IPTABLES REJECT]: IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:52:54:0d:00:23:01:08:00 SRC=153.121.33.75 DST=153.121.33.255 LEN=229 TOS=0x00 PREC=0x00 TTL=64 ID=15869 PROTO=UDP SPT=138 DPT=138 LEN=209 Mar 21 16:03:03 refirio kernel: [IPTABLES REJECT]: IN=eth0 OUT= MAC=01:00:5e:00:00:01:b8:ca:3a:62:cc:e0:08:00 SRC=0.0.0.0 DST=224.0.0.1 LEN=32 TOS=0x00 PREC=0xC0 TTL=1 ID=0 DF PROTO=2 Mar 21 16:03:32 refirio kernel: [IPTABLES REJECT]: IN=eth0 OUT= MAC=52:54:0d:00:23:10:00:24:38:2d:06:00:08:00 SRC=89.248.166.153 DST=153.121.33.84 LEN=40 TOS=0x00 PREC=0x00 TTL=19 ID=26437 PROTO=TCP SPT=3389 DPT=3389 WINDOW=50723 RES=0x00 SYN URGP=50723
「SRC=89.248.166.153」の部分で送信元IPアドレスが判る 「DST=153.121.33.84」の部分で送信先IPアドレスが判る この場合、オランダからrefirio.netにアクセスがあり、そのアクセスを遮断したと判る 送信元IPアドレスがプライベートIPアドレスの場合、送信元が偽装されている可能性が高い これらは接続は拒否しておくといい プライベートIPアドレスの範囲は以下のとおり 10.0.0.0/8(10.0.0.0 〜 10.255.255.255) 172.16.0.0/12(172.16.0.0 〜 172.31.255.255) 192.168.0.0/16(192.168.0.0 〜 192.168.255.255) 以下の送信元も偽装されている可能性が高い これらも接続は拒否しておくといい 127.0.0.0/8 169.254.0.0/12 192.0.2.0/24 224.0.0.0/4 224.0.0.0/5 「SPT=138」の部分でソースポート番号(送信元のポート番号)が判る 「DPT=138」の部分でデスティネーションポート番号(送信先のポート番号)が判る 同じIPアドレスから色々なポートに対してアクセスがあれば、ポートスキャンの可能性がある 以下のログは基本的なファイヤーウォールのログなので無視していい?
May 7 18:21:49 refirio kernel: [IPTABLES REJECT]: IN=eth0 OUT= MAC=01:00:5e:00:00:01:b8:ca:3a:62:cc:e0:08:00 SRC=0.0.0.0 DST=224.0.0.1 LEN=32 TOS=0x00 PREC=0xC0 TTL=1 ID=0 DF PROTO=2
止まらない SRC 0.0.0.0 DST 224.0.0.1 http://luluya.mydns.jp/d_pukiwiki/index.php?%E3%81%82%E3%81%9F%E3%81%BE%E3%81%AE%E3%81%AA%E3%81%8B%2... strange kernel log message appeared http://www.linuxquestions.org/questions/linux-server-73/strange-kernel-log-message-appeared-41754352... AbuseIPDB - IP address abuse reports - Making the Internet safer, one IP at a time https://www.abuseipdb.com/ ■CentOS7のfirewallでの具体例 以下はCentOS7のfirewallで、中国からのアクセスを拒否した際のログ(説明用に若干改変してある) ログ形式はCentOS6のiptableと同じみたい
Apr 21 15:20:47 refirio kernel: FINAL_REJECT: IN=eth0 OUT= MAC=52:54:0d:00:23:10:00:1b:ed:b0:c1:00:08:00 SRC=122.4.199.68 DST=153.121.33.84 LEN=40 TOS=0x00 PREC=0x00 TTL=50 ID=60580 DF PROTO=TCP SPT=21667 DPT=2222 WINDOW=39862 RES=0x00 ACK RST URGP=0
ログの意味は以下のとおり 先頭領域: Apr 21 15:20:47 ... 4月21日15時20分47秒に記録された refirio kernel ... refirioサーバ FINAL_REJECT ... firewallコマンドによるデフォルトのラベル(?) MACレイヤ(L2): IN=eth0 ... NIC eth0へのアクセス(?) OUT= ... 例えば eth1 とあればNIC eth1からのアクセス(?) MAC=52:54:0d:00:23:10:00:1b:ed:b0:c1:00:08:00 ... refirioサーバのNICのMacアドレス(?) IPレイヤ(L3): SRC=122.4.199.68 ... ソースIPアドレス / 送信元アドレスは 122.4.199.68 (中国) DST=153.121.33.84 ... デスティネーションIPアドレス / 送信先アドレスは 153.121.33.84 (refirio.net) LEN=40 ... パケットの長さ TOS=0x00 ... IPヘッダ TOSフィールドの値 PREC=0x00 ... IPヘッダ TOSフィールド内、PRECEDENCEの値 TTL=50 ... IPヘッダ TTLの値 ID=60580 ... IPヘッダ IDの値 DF ... IPヘッダ Flag の DFビット(Don’t Fragment)が立っている場合 PROTO=TCP ... プロトコル / TCP TCPレイヤ(L4): SPT=21667 ... ソースポート番号 / 送信ポート番号は21667 DPT=2222 ... デスティネーションポート番号 / 送信ポート番号は2222 WINDOW=39862 ... TCP Window RES=0x00 ... Reservedの値 ACK RST ... Control Bitsのそれぞれに対応(URG、ACK、PSH、RST、SYN、FIN) URGP=0 ... Urgent Pointerの値 ■Control Bits(制御ビット)について TCP/IPでコネクションを確立する時、終了するときに特定の制御ビットを送受信する 例えば接続確立の際には以下のやりとりが行われる。3ステップによって行われるため、「3ウェイハンドシェイク」と呼ばれる 1. クライアントからSYNパケットを送る 2. サーバからACK+SYNパケットが返される 3. クライアントからACKパケットを送ってコネクションを確立 ポートが空いていなかった場合、2でサーバからACK+RSTが返されて終了する また、接続終了の際には以下のやりとりが行われる 1. クライアントからFIN+ACKパケットを送る 2. サーバからACKパケットが返される 3. その後しばらくしてサーバからもFIN+ACKが送られてくる 4. クライアントからACKパケットを送ってコネクションを終了 制御ビットには以下がある URG ... urgent ACK ... acknowledgement PSH ... push RST ... reset SYN ... synchronize FIN ... finish
■firewall-masqを編集する
/etc/sysconfig/iptables を直接設定せず、/etc/ppp/firewall-masq で設定する方法もある
# vi /etc/ppp/firewall-masq … firewall-masq を編集 # sh /etc/ppp/firewall-masq … firewall-masq を実行(iptables更新)
以下によると、/etc/sysconfig/iptables はインターネット接続時に自動で実行されるファイルらしい つまり、インターネットに接続されたらファイヤーウォールが有効になるみたい Linuxルーター構築(rp-pppoe+iptables) - CentOSで自宅サーバー構築 https://centossrv.com/linux-router.shtml
■Tripwire(ファイル改ざん検知システム)導入
ファイル改竄検知システム導入(Tripwire) http://centossrv.com/tripwire.shtml 上の方法ではEC2にインストールできなかったが、 yum install --enablerepo=epel tripwire とすればインストールできた AmazonLinuxでTripwireを使ってみる http://rikuga.me/2014/11/10/amazonlinux%E3%81%A7tripwire%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%B... …と思ったが、チェックしようとすると以下のようなエラーが表示された ファイルを頻繁に更新するサイトでは煩わしいだけなので、いったんアンインストール(監視対象を限定できるのなら有用かも?要調査)
### Warning: File system error. ### Filename: /dev/kmem
■代替案 監視対象を限定しないと毎日大量の監視結果が送られてくるので煩わしい が、あまり限定すると改ざん検知の意味が薄れるので難しいところ 以下のコマンドで更新日が10日以内のファイルを表示できるので これを応用して必要なときに改ざんを調査する方がいいかも
# find ./ -mtime -11 -ls
■Rootkit Hunter(rootkit検知ツール)導入
※コマンドの改ざんだけでなく、アカウントの状態やアプリケーションのバージョンなども診断してくれる ※chkrootkitよりも判りやすいかもしれないが、設定の最適化をしないと警告がたくさん来る。要勉強
# yum install rkhunter … Rootkit Hunter をインストール # rkhunter --update … rootkit情報のデータベースをアップデート # rkhunter --check … チェックを実行
■chkrootkit(rootkit検知ツール)導入
※Rootkit Hunterの方が判りやすいかも? rootkit検知ツール導入(chkrootkit) http://centossrv.com/chkrootkit.shtml EC2では以下を参考にインストールできた Amazon EC2でマルウェアであるルートキットを検出する - chkrootkit / rkhunter - http://dev.classmethod.jp/cloud/amazon-ec2-rootkit/
■fail2ban(侵入防御ツール)導入
# yum install fail2ban # vi /etc/fail2ban/jail.local … 設定ファイルを編集(/etc/fail2ban/jail.conf は直接編集しない)
[ssh-iptables] enabled = true … 設定を有効にする filter = sshd … フィルタ名 action = iptables[name=SSH, port=10022, protocol=tcp] … アクション sendmail-whois[name=SSH, dest=root, sender=fail2ban@refirio.net] logpath = /var/log/sshd.log … 監視するログファイル maxretry = 5 … 最大リトライ回数
※上の設定で「SSHでの接続に5回失敗すれば、接続元をブロックする」となる
# service fail2ban start … fail2banを起動 fail2ban を起動中: [ OK ] # chkconfig fail2ban on … fail2banの自動起動を設定 # iptables -L … iptablesの内容を確認 Chain fail2ban-SSH (1 references) … 最後に設定が追加されている target prot opt source destination RETURN all -- anywhere anywhere
※/etc/sysconfig/iptables を編集してiptablesを再起動した場合、 iptablesにあるfail2banの設定内容が消えるので、fail2banを再起動する必要がある? 自動起動に設定しておけば問題ない?
■ClamAV(アンチウィルスソフト)導入
ユーザがWebサーバにファイルをアップロードするようなサービスの場合、 アンチウィルスソフトを導入しておくといい ■検証サーバについて 2020年3月時点で、AWSのEC2を使って検証 t2.micro だとメモリ不足でデーモンを起動できなかった t2.small なら起動できた 他の解説でも「t2.microでは動かなかった」のように書かれている ■前準備 HTTPで疎通確認できるようにしておく
$ sudo su - # localectl set-locale LANG=ja_JP.UTF-8 # timedatectl set-timezone Asia/Tokyo # amazon-linux-extras list # amazon-linux-extras install nginx1.12 -y # systemctl start nginx # systemctl enable nginx
http://203.0.113.1/ ■インストール Amazon Linux 2にClamAVをインストールする - Qiita https://qiita.com/aosho235/items/e70ccf3b7464369bebab
# amazon-linux-extras install -y epel … epelをインストール # yum install -y clamav clamav-update clamd … ClamAVをインストール # vi /etc/freshclam.conf … 定義ファイル更新の設定ファイルを編集(何も変更しなくても動く) # freshclam … 定義ファイル更新(20秒程度で更新できた。大した負荷も無かった) # vi /etc/cron.d/clamav-update … 自動更新のファイルが自動で作られている # vi /etc/clamd.d/scan.conf … スキャンの設定ファイルを編集
#LogFile /var/log/clamd.scan ↓ LogFile /var/log/clamd.scan #LocalSocket /run/clamd.scan/clamd.sock ↓ LocalSocket /run/clamd.scan/clamd.sock #LocalSocketMode 660 ↓ LocalSocketMode 660 #ExcludePath ^/proc/ #ExcludePath ^/sys/ ↓ ExcludePath ^/proc/ ExcludePath ^/sys/ User clamscan ↓ #User clamscan
# systemctl start clamd@scan … デーモンを起動 # systemctl enable clamd@scan … 自動起動を設定
ログは以下で表示できる
# journalctl -u clamd@scan
上記の手順で設定した場合、以下からもログを表示できる
# vi /var/log/clamd.scan
上記設定で freshclam は自動更新されるが、この実行タイミングはウイルススキャンの実行タイミングとは別物 あくまでもウイルス定義ファイル更新に関する設定 ■手動スキャン 以下でスキャンを手動実行できる。15秒程度で完了した
# clamscan -r -i ~ ----------- SCAN SUMMARY ----------- Known viruses: 6775136 Engine version: 0.102.2 Scanned directories: 2 Scanned files: 6 Infected files: 0 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 15.473 sec (0 m 15 s) 以下でウイルスの検出をテストできる。自動で隔離されたりはしなかった # curl -O https://www.eicar.org/download/eicar.com # clamscan -r -i ~ /root/eicar.com: Win.Test.EICAR_HDB-1 FOUND ----------- SCAN SUMMARY ----------- Known viruses: 6775136 Engine version: 0.102.2 Scanned directories: 2 Scanned files: 7 Infected files: 1 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 15.932 sec (0 m 15 s) 以下で「/root/test 内をスキャンして、ウイルスがあれば /root/infected に隔離する」となる # clamscan -i -r /root/test --move=/root/infected /root/test/eicar.com: Win.Test.EICAR_HDB-1 FOUND /root/test/eicar.com: moved to '/root/infected/eicar.com' ----------- SCAN SUMMARY ----------- Known viruses: 6775136 Engine version: 0.102.2 Scanned directories: 1 Scanned files: 1 Infected files: 1 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 15.889 sec (0 m 15 s)
■メモリ使用量の検証 スキャンを手動実行すると、実行するたびにウイルス定義ファイル(500〜700MBくらい)を読み込んでからスキャンする デーモンとして起動しておくと ・起動時に1度だけウイルス定義ファイルを読み込んで常駐する(ただし読み込み内容を、デーモンがメモリ上に保持し続ける) ・1日1回アクセスの少ない早朝の時間帯にフルスキャンを行ってくれる となる ウイルス定義ファイルの読み込みには時間がかかるので、毎回読み込むと 「送受信するメールのスキャンに時間がかかり、メールの送受信が遅延する」 となってしまう可能性がある よって迅速なスキャンが必要でメモリが潤沢にあるサーバの場合、デーモンとして起動しておくといい 迅速なスキャンが不要で、メモリが潤沢でなく、1日に数回スキャンすれば十分…のような場合、手動スキャンも検討する 誤検知によって無害なファイルを削除してしまわないように、検出しても自動で削除せずにメールで通知するなどする ClamAVによる定期ウイルススキャンの設定 | 稲葉サーバーデザイン https://inaba-serverdesign.jp/blog/20170913/clamav_scan_virus_install.html nginxとPHPだけを入れた程度のEC2(t2.small)を用意し、 ClamAVをインストールしてデーモンとして実行すると、メモリ2GBのうち1GBくらいが常に使用中になった psコマンドで確認すると、以下のプロセスがあった
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 3875 0.0 43.7 1088308 892968 ? Ssl Mar17 0:14 /usr/sbin/clamd -c /etc/clamd.d/scan.conf
以下のコマンドでClamAVを終了させると上記プロセスは無くなり、 使用中のメモリも100MBくらいになった
# systemctl stop clamd@scan # systemctl disable clamd@scan
以下はデーモン起動中のメモリ
# free total used free shared buff/cache available Mem: 2039156 997756 289164 456 752236 883624 Swap: 0 0 0
以下はデーモン終了後のメモリ
# free total used free shared buff/cache available Mem: 2039156 105792 1180996 456 752368 1775596 Swap: 0 0 0
上記の 「デーモン化すると、ウイルス定義ファイルの内容をメモリ上に保持し続けている」 と思われる挙動が確認できた ■手動スキャンとメモリ使用量の考察 なるべくメモリの消費を抑えるスキャンを検証 全体をスキャン
# clamscan -i -r /
以下のようにしても同じ
# clamscan --infected --recursive /
全体をスキャンすると、以下のようなエラーが大量に表示される ファイルシステム sysfs・proc などは仮想ファイルが置かれる場所で実態が存在しないため、スキャンするとエラーになる
WARNING: Can't open file /sys/module/crc_ccitt/uevent: Permission denied LibClamAV Warning: fmap_readpage: pread fail: asked for 4095 bytes @ offset 1, got 0
ファイルシステムを跨がないで全体をスキャン。6分ほどでスキャンできたが、長く使っているサーバならもっと時間がかかる
# clamscan --infected --recursive --cross-fs=no / /root/infected/eicar.com: Win.Test.EICAR_HDB-1 FOUND ----------- SCAN SUMMARY ----------- Known viruses: 6779666 Engine version: 0.102.2 Scanned directories: 5416 Scanned files: 47703 Infected files: 1 Data scanned: 1700.70 MB Data read: 1537.74 MB (ratio 1.11:1) Time: 345.612 sec (5 m 45 s)
対象を限定してスキャン。大したコンテンツ量では無いので、20秒ほどでスキャンできた
# clamscan --infected --recursive --cross-fs=no /usr/share/nginx ----------- SCAN SUMMARY ----------- Known viruses: 6779666 Engine version: 0.102.2 Scanned directories: 30 Scanned files: 367 Infected files: 0 Data scanned: 8.62 MB Data read: 5.54 MB (ratio 1.56:1) Time: 19.300 sec (0 m 19 s)
巨大過ぎるファイルはスキャンに失敗するので、2MB以上のファイルはスキャン対象から省く
# clamscan --infected --recursive --cross-fs=no --max-filesize=2048M --max-scansize=2048M /usr/share/nginx ----------- SCAN SUMMARY ----------- Known viruses: 6779666 Engine version: 0.102.2 Scanned directories: 30 Scanned files: 367 Infected files: 0 Data scanned: 8.62 MB Data read: 5.54 MB (ratio 1.56:1) Time: 17.805 sec (0 m 17 s)
ウイルスが検出された例
# clamscan --infected --recursive --cross-fs=no --max-filesize=2048M --max-scansize=2048M /usr/share/nginx /usr/share/nginx/html/clamav/eicar.com: Win.Test.EICAR_HDB-1 FOUND ----------- SCAN SUMMARY ----------- Known viruses: 6779666 Engine version: 0.102.2 Scanned directories: 30 Scanned files: 368 Infected files: 1 Data scanned: 8.62 MB Data read: 5.54 MB (ratio 1.56:1) Time: 18.102 sec (0 m 18 s)
運用の際は上記コマンドをスクリプトから実行し、「FOUND」という文字があればメールで通知…とすれば良さそう 誤検知によって無害なファイルを削除してしまわないように、検出しても自動で削除せずにメールで通知するなどする システム全体をスキャンすると時間がかかるので、一般ユーザがコンテンツを配置する可能性のある場所のみスキャンするか (Webサーバなら、「公開ディレクトリのみ」「アップロードファイルの保存場所のみ」など) ClamAVによる定期ウイルススキャンの設定 | 稲葉サーバーデザイン https://inaba-serverdesign.jp/blog/20170913/clamav_scan_virus_install.html IT とかその他もろもろ: ClamAV でウィルススキャン http://fishrimper.blogspot.com/2014/10/clamav.html ■エラー
# systemctl start clamd@scan … デーモンを起動したときにエラーになった Job for clamd@scan.service failed because the control process exited with error code. See "systemctl status clamd@scan.service" and "journalctl -xe" for details. # journalctl -xe … 詳細を表示。メモリ不足で動かないみたい。t2.microでは厳しいのだと思われる
Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: mpool_malloc(): Can't allocate memory (262144 bytes). Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: cli_parse_add(): Problem adding signature (2). Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: Problem parsing database at line 89191 Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: Can't load main.ndb: Malformed database Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: cli_tgzload: Can't load main.ndb Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: Can't load /var/lib/clamav/main.cvd: Malformed database Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: LibClamAV Error: cli_loaddbdir(): error loading database /var/lib/clamav/main.c Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: Malformed database Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal clamd[513]: ERROR: Malformed database Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal systemd[1]: clamd@scan.service: control process exited, code=exited status=1 Mar 17 04:28:06 ip-10-0-1-170.ap-northeast-1.compute.internal systemd[1]: Failed to start clamd scanner (scan) daemon. -- Subject: Unit clamd@scan.service has failed -- Defined-By: systemd -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel -- -- Unit clamd@scan.service has failed. -- -- The result is failed.
■メモ Amazon Linux 2にClamAVをインストールする - Qiita https://qiita.com/aosho235/items/e70ccf3b7464369bebab Linuxアンチウイルスソフト ClamAV - Qiita https://qiita.com/bezeklik/items/4696e15c889ffff6bc41 clamscanとclamdscanの使用方法 - tech.farend http://tech.farend.jp/blog/2015/12/28/using-clamav/ アンチウイルスソフト導入(Clam AntiVirus) - CentOSで自宅サーバー構築 https://centossrv.com/clamav.shtml ClamAVによる定期ウイルススキャンの設定 | 稲葉サーバーデザイン https://inaba-serverdesign.jp/blog/20170913/clamav_scan_virus_install.html CentOS 7: ClamAVでウィルススキャンを実行する - Narrow Escape https://www.hiroom2.com/2017/06/06/centos-7-clamav%E3%81%A7%E3%82%A6%E3%82%A3%E3%83%AB%E3%82%B9%E3%8... VirtualBox+CentOS7環境に、ClamAVをdaemonで起動するようにインストールする - Qiita https://qiita.com/mopoki2696/items/dfc19a4a0b51b3bbace6 ClamAVのエラー LibClamAV Error: mpool_malloc(): Attempt to allocate bytes. | OrangeGardenRoom http://blog.grandaria.com/?p=204
■ClamAV(アンチウィルスソフト)導入(昔試したときのメモ)
アンチウイルスソフト導入(Clam AntiVirus) http://centossrv.com/clamav.shtml ログから”SelfCheck: Database status OK”を消すの巻 http://blog.trippyboy.com/2011/%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3/%E3%83%AD%E3%8... Linuxでの効果的なAntivirus の設定と運用 https://oss.sios.com/security/antivirus-security-20161108 デフォルトでは /var/log/messages に対して、10分ごとに「SelfCheck: Database status OK.」というログが書き出されるのを無効に。 (ここには、もっと重要なログが出力されるべき)
# vi /etc/freshclam.conf … 設定ファイルを編集
#LogSyslog yes … コメントアウトする
# vi /etc/clamd.conf … 設定ファイルを編集
#LogSyslog yes … コメントアウトする
※Clamはfreshclam.confを読み込んだあとにclamd.confを読む。 freshclam.confで設定されていない内容はclamd.confの内容が反映されると思われる。(要検証)
# service clamd restart … Clam AntiVirus を再起動
(EC2 では service clamd.scan restart としないと再起動できない?) ■負荷対策に試したこと ウイルススキャンはCPUやメモリなどの消費が大きいので、Zabbixなどで監視している場合は警告が頻繁に来る 「CentOSで自宅サーバー構築」で紹介されているスクリプトを使っている場合、 以下のようにするとスキャン対象から除外できる(負荷の問題で、この2つは除外しておいた方がいいみたい) が、それでも負荷が高い
echo "/proc/" >> clamscan.exclude echo "/sys/" >> clamscan.exclude
以下を clamscan.exclude に設定するといいかも つまり /home/ と /var/www/ のみチェック(EC2の場合)。必要に応じてチェック対象は追加 (シェルスクリプトを編集するよりは、設定ファイルの編集に留めた方が安全) それでもZabbixのアラームが飛ぶサーバがある
/bin/ /boot/ /cgroup/ /dev/ /etc/ /lib/ /lib64/ /local/ /lost+found/ /media/ /mnt/ /opt/ /proc/ /root/ /run/ /sbin/ /selinux/ /srv/ /sys/ /tmp/ /usr/ /var/account/ /var/cache/ /var/crash/ /var/cvs/ /var/db/ /var/empty/ /var/games/ /var/kerberos/ /var/lib/ /var/local/ /var/lock/ /var/log/ /var/nis/ /var/opt/ /var/preserve/ /var/run/ /var/spool/ /var/tmp/ /var/yp/
CPU使用率を抑えて実行する方法はあるらしい?要勉強 http://dev.classmethod.jp/cloud/aws/clamav-process-controled-by-cgroup/ 一般ユーザにファイルアップロードを許可していないのなら、 ウイルスチェックは普段停止させておいて、自動起動もOFFにしておく方がいいかも 月に一回など、定期的にウイルスチェックを行うなどで十分かも
# service clamd.scan stop # chkconfig clamd off # cd /etc/cron.daily/ # rm virusscan
■ウェブサイトへの攻撃を検出する
# cd /var/log/httpd/ … Apacheログがある場所へ移動 # tar zcvf /var/www/logs/httpd_log_201412.tar.gz ./access_log ./access_log-20141207 ./ssl_access_log ./ssl_access_log-20141207 … 各ログのタイムスタンプを確認し、前月の範囲すべてのログをアーカイブする
IPA提供のウェブサービスを利用 http://www.ipa.go.jp/security/vuln/iLogScanner/ 以下の設定で検査を行う アクセスログ形式:Apache1.3系/2.0系/2.2系のcommonタイプ 解析対象アクセスログファイル名:解答したアクセスログをまとめて選択 出力先ディレクトリ:任意 詳細解析ボタンを押して… ログフォーマット:無視 開始日:先月の1日 終了日:前月の末日 解析レベル:詳細 解析開始ボタンを押して、ひたすら待つ IPアドレスから身元を調べる http://www.ip-inspector.com/
■ログサーバ
ログを改ざんされても攻撃の解析ができるように、ログは専用のログサーバに転送しておくといい rysslogでログの転送を行うなど(rysslogは未検証)
■メモ
ざっくり概要!Linuxセキュリティに関する基礎知識まとめ https://eng-entrance.com/linux-security-basic

Advertisement