user「PPAP」からの不正アクセスを検出しました〜sshdのログ(/var/log/secure)から不正ユーザの名前を取り出し、セキュアじゃないユーザ名について考えてみた〜
存在しないユーザからのアクセスがあった
Failed password for invalid user *** from ...
これは、
「linux上で登録されていないユーザ *** からのアクセスがありました」
ということ。
今回、攻撃者がどんな名前を用いてアクセスしてくるのか
探ってみる。
手順
ログからinvalid userだけ取り出す
awkを使おう。
cat /var/log/secure | awk -F' ' '/Invalid/{print$ 8}' | sort | uniq
0 1 1111 111111 123123 1234 12345 123456 123456789 12345qwert 1234qwer 12qwaszx 1q2w3e4r 1q2w3e4r5t 1qaz2wsx 1qaz@WSX
出てきた。
ついでに集計もしてみる。
cat secure | awk -F' ' '/Invalid/{print$ 8}' | awk '{count[$0]++}END{for(i in count)print count[i], i}' | sort -nr
15 minecraft 14 www 14 user1 14 steam 14 server 14 debian
出てきた。
不正アクセス者ランキング
5位
centos: 1023件
なお、ubuntuは63件でした。
単純にサーバとしてよく使われているから・・・?
それともnmapでOSがわかるから・・・?
(自分のサーバにnmapしてみましたが、unixという情報しか出てきませんでした)
4位
guest: 1096件
ありがち。
3位
user: 1126件
これもありがち。
2位
test: 1178件
これすごくありがち。
1位
admin: 1300件
これやったことあるな。
これからは安易に使わないようにしよう。。。
なお、6位から20位はこんな感じ。
順位 | 回数/month | ユーザ名 |
---|---|---|
6 | 112 | oracle |
7 | 98 | nagios |
8 | 90 | git |
9 | 63 | ubuntu |
10 | 54 | hadoop |
11 | 52 | pi |
12 | 46 | ftpuser |
13 | 43 | teamspeak |
14 | 41 | zabbix |
15 | 41 | vagrant |
16 | 37 | vnc |
17 | 37 | ubnt |
18 | 35 | support |
19 | 31 | ts |
20 | 30 | ts3 |
上位5位が圧倒的すぎる。
分類
数字 + ランダムアルファベット系
0 1 1111 111111 123123 1234 12345 123456 123456789
管理者系
ADMIN Admin123 Administrator admin admin1 admin123 admin2 administrador administrator
有名人系
adam eva
特定のクラウドサービスを狙ったもの
ec2-user
人名系
外国人
alberto aleksei alessandro alex alfresco ali alice alicia allison ally alma
日本人
dai daichi daiki daisuke hideaki hideki hideo hikaru hiro hiroaki hiroki hiroshi hiroyuki
ソフトウェア名
nagios git hadoop nginx nodejs redis vagrant
デプロイ用ユーザを狙ったと思われる系
deploy1 deploy123 deploy1234 deploy12345 deploy123456 deploy2 deploy3 deploy4 deploy5
明らかに悪意がある系
exploit
番外編
PPAP
これで日本人だと特定できたかなと思ったのもつかの間、
これ世界的に流行ったやつだからどこからアクセスされてもおかしくねえぞ。
まとめ
user名で避けるべき名前
- admin
- test
- user
- guest
- centos
よく使われているからこそ、狙われる。
感想
割と日本人の名前が多い。
どこまで考えて攻撃しているのかはしらないけど、
安易に自分の名前をユーザ名にするのは良くないと感じた。
せめて記号や数値と織り交ぜたい。
また、ソフトウェア名も良くない。
僕が借りているサーバが、世界各国から「1日900回」不正アクセスされている話〜/var/log/secureからみえる攻撃者の影〜
私用で使っているサーバの/var/log/secureをみてみた
見に覚えのないアクセスが大量にある。。。
しかもuserはrootだったりadminだったり。。。
これ、不正アクセスってやつか?
1日どれくらい不正アクセスを試みられているのか
2/4の不正アクセス回数を、すごい雑な方法だけどしらべてみた。
$ cat /var/log/secure | awk '/Feb 4/ && /Failed/' | wc -l 943
わお。943回。どこから不正アクセスされているんだろ。
いったんipだけ抽出して、
どこの国から狙われているか調査してみた。
使用unixコマンド
ここらへんを知っておくとログ調査に便利。
調査手順
ipアドレスのみ抽出
$ grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /var/log/secure > ips.txt
-Eオプションで正規表現が使えます
40.69.203.57 40.69.203.57 40.69.203.57 172.31.32.142 94.183.180.86 94.183.180.86 94.183.180.86 ...
※ 念のためipアドレスは編集しております
ipの重複をなくす
sort ips.txt | uniq > unique_ips.txt
sortしてuniqして、ipをuniqueにします。
101.78.196.27 103.16.142.208 103.20.251.158 103.213.115.45 103.216.205.51 103.22.171.1 ...
ipがユニークになった。
ipジオロケーションサービスに投げる
$ curl http://api.hostip.info/get_html.php\?ip=40.69.203.57
これを投げると、
Country: UNITED STATES (US) City: (Unknown city) IP: 40.69.203.57
いい感じにデータが返ってきます。
#!/bin/bash while read ip do curl http://api.hostip.info/get_html.php\?ip=$ip\&position=true done < unique_ips.txt
run.shという名前で保存して、
$ sh run.sh > countries.txt
こんな感じで走らせ、結果をテキストファイルに保存します。
awkコマンドで国だけ抽出
$ cat countries.txt | awk '/Country/' | sort | uniq
とすると、先ほどの結果の「Country」だけ抽出できます。
結果
Country: (Private Address) (XX) Country: (Unknown Country?) (XX) Country: AUSTRALIA (AU) Country: AUSTRIA (AT) Country: BRAZIL (BR) Country: BULGARIA (BG) Country: CANADA (CA) Country: CHILE (CL) Country: CHINA (CN) Country: COLOMBIA (CO) Country: CROATIA (HR) Country: DENMARK (DK) Country: EUROPEAN UNION (EU) Country: FRANCE (FR) Country: GERMANY (DE) Country: HONG KONG (HK) Country: HUNGARY (HU) Country: INDIA (IN) Country: INDONESIA (ID) Country: IRELAND (IE) Country: ISRAEL (IL) Country: ITALY (IT) Country: JAPAN (JP) Country: KOREA, REPUBLIC OF (KR) Country: MALAYSIA (MY) Country: MEXICO (MX) Country: NETHERLANDS (NL) Country: NORWAY (NO) Country: PAKISTAN (PK) Country: PERU (PE) Country: PHILIPPINES (PH) Country: POLAND (PL) Country: RUSSIAN FEDERATION (RU) Country: SENEGAL (SN) Country: SLOVENIA (SI) Country: SPAIN (ES) Country: SWITZERLAND (CH) Country: TAIWAN (TW) Country: THAILAND (TH) Country: UKRAINE (UA) Country: UNITED KINGDOM (GB) Country: UNITED STATES (US) Country: VIET NAM (VN)
おおー。
世界各国から狙われている笑
攻撃元を特定するのは難しい
ただ、これだけだと発信元を特定するのは難しい。
攻撃者はいくつもの踏み台サーバを使って攻撃することにより、
自分の発信元を特定しにくくしているから。
なので、世界各国からアクセスされているからと言って、
本当に世界各国の人が狙っているかどうかはわからない。
攻撃を回避するには
色んな方法があるが、
今回はポート番号を変えてみた(次回)
puttyからsshでログインしようとした時に、Disconnected: No supported authentication methods availableと言われてしまった
puttyを使ってsshでパスワード認証を使ってログインしようとした
こんなエラーが表示されました。
Disconnected: No supported authentication methods available
とりあえずサーバに入り、/etc/ssh/sshd_configをみてみる
いろいろな原因が考えられるが、とりあえずサーバの設定ファイルをみてみた。
PasswordAuthentication no
パスワード認証が使えないように設定されている。
だいぶ前にいじったから忘れてた。
セキュアじゃなくなるけど
一旦
PasswordAuthentication yes
とした。そうしたらログインできるようになった。
その後、すぐにnoに戻した。
Angularを使って、カートで商品を選択する画面を作ってみた〜親子コンポーネント・サービス間連携をしてみる〜
Angularの復習をしようと思った
今回の開発で、Angularを使った。
基本フロント側は一人で開発をしていたが、
1画面で扱っているコンポーネントの数が600個をこえたり、
画面間で引き継ぐ項目がどんどん増えてきたりで、
だんだん大変なことになってきた。
なぜ大変な事になってきたか
サービス増えすぎ問題
それぞれのコンポーネントで値(以下、モデル)を共有させようとした時に、
サービスをDIして共有させていた。
モデルごとにサービスを作ってしまっていたので、
モデルが増えるたびにサービスが増え、大変なことになってしまった。
サービスの役割2つあるよ問題
ページ間をまたがないデータはコンポーネントに持たせればよいのに、
なぜかサービスにデータを持たせてしまっていた。
よって、
サービスが「データの保持」「データ処理」の2つの役割を持ってしまっていた。
サービスの役割が曖昧になり、追加でいじる時にどこをいじればよいのかわかりにくくなってしまっていた。
作ったのがこれ
説明
構成
最上位にAppComponentをおく。
このコンポーネントが、この画面で扱うすべてのプロパティを保持している。
子供はAppComponentのプロパティを共有している。
子供で起こったイベントは、AppServiceを通じてAppComponentに伝えられる。
商品をクリックした時、どのように画面が変更されるか
クリックしたことをAppServiceに伝える
AppServiceは、AppComponentが持っているプロパティを操作する
子コンポーネントに、AppComponentのプロパティ変更が伝わる
子コンポーネントは親のプロパティを共有しているので、
そのまま親のプロパティの変更が伝わります。
画面に結果があらわれる
まとめ
今回、AppComponentに画面上で扱うすべてのプロパティをもたせたので、
シンプルになった。
また、AppServiceを用いたことにより、
子供から親へのイベントバブリングと言った複雑なことをしなくても良くなった。
今後はこういう設計にしていきたいなぁ。
module.exportsとは何か、どうもわからなかったので実験してみた〜Node.jsにて外部moduleをrequireする〜
いきさつ
今まで何も考えずに
npm install
して、
var module = require('module-name');
して使ってきたが、
Node.jsについて知らなさすぎて、
node_moduleディレクトリ配下に格納されているmoduleをみても、
ぜんぜん読めないことに気づいた。
exports.moduleが分かればだいぶ読めるようになるかな、と思い、
まずはexports.moduleについて理解することにした。
ディレクトリ構造
├── main.js └── node_modules └── weather-module.js
やってること
main.jsからweather-module.jsを読み込む。
// main.js var weather = require('weather-module'); weather.today(); weather.yesterday();
// weather-module.js /** weatherオブジェクトの生成 */ var weather = {}; weather.today = function() { console.log('晴れだよ'); } weather.yesterday = function() { console.log('雨だったよ'); } module.exports = weather;
わからないこと
module.exports = weather;
の部分で何をやっているのかわからない。
結論
// main.js require('weather-module');
requireが、
weather-module.jsでmodule.exportsに渡されているオブジェクトを
返してくれるので、それを使用することができる。
実験手順
何を読み込んでいるのか調べる
これを外部ファイル(main.js)から読み込んで使いたい。
// main.js var weatherModule = require('weather-module'); console.log(weatherModule);
main.jsを実行
$ node main.js { today: [Function], yesterday: [Function] }
weatherオブジェクトそのものが渡っているようである。
weatherオブジェクトはmodule.exportsに渡されているのものなので、
require('weather-module');
はmodule.exportsに渡されているオブジェクトを返す、と考えられる。
module.exportsに複数のオブジェクトを渡してみる
/** weatherオブジェクトの生成 */ var weather = {}; weather.today = function() { console.log('晴れだよ'); } /** 関数の追加2 */ weather.yesterday = function() { console.log('雨だったよ'); } /** temperatureオブジェクトの生成 */ var temperature = {}; temperature.today = function() { console.log('25'); } temperature.yesterday = function() { console.log('15'); } module.exports = { weather: weather, temperature: temperature // もう一個渡す };
main.jsを実行
$ node main.js { weather: { today: [Function], yesterday: [Function] }, temperature: { today: [Function], yesterday: [Function] } }
やはり、
require('weather-module');
module.exportsに渡されているオブジェクトを返すようだ。
まとめ
require('hoge-module');
hoge-module.jsにて、
module.exportsに渡されているオブジェクトを返す。
逆に言えば、
module.exportsに渡していないオブジェクトは使えない。
外部から使用したいオブジェクトは、必ずmodule.exportsに渡すこと。
参考
本番環境にテストデータを入れてしまったときは、deleteではなくtruncateでテーブルからレコードを一掃しよう〜deleteとtruncateの違い〜
いきさつ
社内で使用するシステムの開発が一旦落ち着いたので、
本番環境構築することになった。
といってもすでにテスト環境を構築しているので、
慣れたものである。
種々のインスタンスを立ち上げ、ansible用のユーザを作成し、
playbookの諸々の設定位置を少し書き換ええ、流すだけで良い。
(playbook、つくるのは大変だった)
で、いつものように本番環境にデプロイし終わり
きちんと登録できるか一通りの操作をした。
そこで先輩が一言
「本番環境上に作ってしまったデータは残してはいけないから、
きちんとtruncateしといてね」
僕はハッとした
当たり前だが、その一言に僕はハッとさせられた。
基本的に本番環境はまっさらな状態で、お客さんに使ってもらう。
使ってもらう時、
私たち開発者がテスト用に打ったゴミデータが入っていると、
アカウント管理をしているとはいえ、
万が一そのゴミデータのせいでバグが起こりうる場合もある。
(そもそも本番環境なので、
テストデータが紛れ込んでいると言うのはおかしい、というのもある)
なので
テストデータは消しておく必要がある。
そのときに注意しておくのがdeleteとtruncateの違いだ。
deleteとtruncateの違い
idがauto_incrementになっていた場合、
deleteは連番情報を保持したまま。
truncateは1から裁判し直す。
という違いがある。
まっさらな状態にする、という意味ではtruncateが適している。
まとめ
本番環境の扱いには気をつけよう。