君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

user「PPAP」からの不正アクセスを検出しました〜sshdのログ(/var/log/secure)から不正ユーザの名前を取り出し、セキュアじゃないユーザ名について考えてみた〜

f:id:karoten512:20180210130018j:plain

存在しないユーザからのアクセスがあった

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件でした。

なぜubuntuじゃなくてcentosなのか。

単純にサーバとしてよく使われているから・・・?

それともnmapでOSがわかるから・・・?

(自分のサーバにnmapしてみましたが、unixという情報しか出てきませんでした)

4位

guest: 1096件

ありがち。

3位

user: 1126件

これもありがち。

2位

test: 1178件

これすごくありがち。

1位

admin: 1300件

これやったことあるな。

これからは安易に使わないようにしよう。。。

なお、6位から20位はこんな感じ。

順位回数/monthユーザ名
6112oracle
798nagios
890git
963ubuntu
1054hadoop
1152pi
1246ftpuser
1343teamspeak
1441zabbix
1541vagrant
1637vnc
1737ubnt
1835support
1931ts
2030ts3

上位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からみえる攻撃者の影〜

f:id:karoten512:20180210104805p:plain

私用で使っているサーバの/var/log/secureをみてみた

f:id:karoten512:20180210112501p:plain

見に覚えのないアクセスが大量にある。。。

しかも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と言われてしまった

f:id:karoten512:20180210003701p:plain

puttyを使ってsshでパスワード認証を使ってログインしようとした

こんなエラーが表示されました。

Disconnected: No supported authentication methods available

とりあえずサーバに入り、/etc/ssh/sshd_configをみてみる

いろいろな原因が考えられるが、とりあえずサーバの設定ファイルをみてみた。

PasswordAuthentication no

パスワード認証が使えないように設定されている。

だいぶ前にいじったから忘れてた。

セキュアじゃなくなるけど

一旦

PasswordAuthentication yes

とした。そうしたらログインできるようになった。

その後、すぐにnoに戻した。

duコマンドを使って、現在いるディレクトリにあるファイルの合計サイズを出したい

f:id:karoten512:20180209233955p:plain

現在いるディレクトリにあるファイルの合計サイズを出したい

$ du -sh .

解説

sオプションについて

sオプションをつけないとどうなるか

$ du -h .
1.2G    ./directoryA
1.2G    ./directoryB
 24K    ./pra

すべてのディレクトリのサイズがでてくる。

つけるとどうなるか

$ du -hs .
3.6G    .

普通に合計値が出る。

hオプションについて

つけないとどうなるか

$ du -s .
7614736 .

512バイト単位で出る。 なぜだ。

つけるとどうなるか

$ du -sh .
3.6G    .

いい感じの単位で出してくれる。

Angularを使って、カートで商品を選択する画面を作ってみた〜親子コンポーネント・サービス間連携をしてみる〜

Angularの復習をしようと思った

今回の開発で、Angularを使った。

基本フロント側は一人で開発をしていたが、

1画面で扱っているコンポーネントの数が600個をこえたり、

画面間で引き継ぐ項目がどんどん増えてきたりで、

だんだん大変なことになってきた。

なぜ大変な事になってきたか

サービス増えすぎ問題

それぞれのコンポーネントで値(以下、モデル)を共有させようとした時に、

サービスをDIして共有させていた。

モデルごとにサービスを作ってしまっていたので、

モデルが増えるたびにサービスが増え、大変なことになってしまった。

サービスの役割2つあるよ問題

ページ間をまたがないデータはコンポーネントに持たせればよいのに、

なぜかサービスにデータを持たせてしまっていた。

よって、

サービスが「データの保持」「データ処理」の2つの役割を持ってしまっていた。

サービスの役割が曖昧になり、追加でいじる時にどこをいじればよいのかわかりにくくなってしまっていた。

作ったのがこれ

f:id:karoten512:20180128205736g:plain

github.com

説明

構成

f:id:karoten512:20180128211839p:plain

最上位にAppComponentをおく。

このコンポーネントが、この画面で扱うすべてのプロパティを保持している。

子供はAppComponentのプロパティを共有している。

子供で起こったイベントは、AppServiceを通じてAppComponentに伝えられる。

商品をクリックした時、どのように画面が変更されるか

クリックしたことをAppServiceに伝える

f:id:karoten512:20180128211859p:plain

AppServiceは、AppComponentが持っているプロパティを操作する

f:id:karoten512:20180128212001p:plain

コンポーネントに、AppComponentのプロパティ変更が伝わる

f:id:karoten512:20180128212033p:plain

コンポーネントは親のプロパティを共有しているので、

そのまま親のプロパティの変更が伝わります。

画面に結果があらわれる

f:id:karoten512:20180128212121p:plain

まとめ

今回、AppComponentに画面上で扱うすべてのプロパティをもたせたので、

シンプルになった。

また、AppServiceを用いたことにより、

子供から親へのイベントバブリングと言った複雑なことをしなくても良くなった。

今後はこういう設計にしていきたいなぁ。

module.exportsとは何か、どうもわからなかったので実験してみた〜Node.jsにて外部moduleをrequireする〜

f:id:karoten512:20180128191834p:plain

いきさつ

今まで何も考えずに

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に渡すこと。

参考

numb86-tech.hatenablog.com

本番環境にテストデータを入れてしまったときは、deleteではなくtruncateでテーブルからレコードを一掃しよう〜deleteとtruncateの違い〜

いきさつ

社内で使用するシステムの開発が一旦落ち着いたので、

本番環境構築することになった。

といってもすでにテスト環境を構築しているので、

慣れたものである。

種々のインスタンスを立ち上げ、ansible用のユーザを作成し、

playbookの諸々の設定位置を少し書き換ええ、流すだけで良い。

(playbook、つくるのは大変だった)

で、いつものように本番環境にデプロイし終わり

きちんと登録できるか一通りの操作をした。

そこで先輩が一言

「本番環境上に作ってしまったデータは残してはいけないから、

きちんとtruncateしといてね」

僕はハッとした

当たり前だが、その一言に僕はハッとさせられた。

基本的に本番環境はまっさらな状態で、お客さんに使ってもらう。

使ってもらう時、

私たち開発者がテスト用に打ったゴミデータが入っていると、

アカウント管理をしているとはいえ、

万が一そのゴミデータのせいでバグが起こりうる場合もある。

(そもそも本番環境なので、

 テストデータが紛れ込んでいると言うのはおかしい、というのもある)

なので

テストデータは消しておく必要がある。

そのときに注意しておくのがdeleteとtruncateの違いだ。

deleteとtruncateの違い

idがauto_incrementになっていた場合、

deleteは連番情報を保持したまま。

truncateは1から裁判し直す。

という違いがある。

まっさらな状態にする、という意味ではtruncateが適している。

まとめ

本番環境の扱いには気をつけよう。