WEBサイトの脆弱性学習に使えるOWASP Mutillidae IIのローカル環境での構築と簡単な使い方の紹介
【追記】
vagrantを立ち上げてすぐにphpmyadmin操作できるように、mutillidae_deploy.shにphpmyadmin/config.inc.php設定ファイルの書き換え処理を追加しました。
===========================================
最近WEBアプリのセキュリティについて勉強しているのですが、今回は実際に手元のローカル環境で手を動かしながら脆弱性を学ぶことができるOWASP Mutillidae IIというWEBアプリを紹介します。WEBアプリのソースは下記のサイトから配布されています。
https://sourceforge.net/projects/mutillidae/sourceforge.net
OWASP Mutillidae IIのローカル環境への構築方法
vagrantで仮想マシンを立ち上げる
OWASP Mutillidae IIアプリは、LAMP環境で動作するのですが、ゼロからLAMP環境を構築するのは少し面倒なのでVagrantfileを作りました。
vagrant up
を実行すれば、OWASP Mutillidae IIアプリのインストールされたvirtual machineがローカル環境上に立ち上がります。vagrantのインストール方法はWEB上にたくさん掲載されているので別サイトで確認してください。
Mutillidae用のデータベースを設定する
vagrant upで仮想マシンが立ち上がった後は、
http://192.168.33.10/mutillidae/ で仮想マシンにブラウザからアクセスします。
下記の画面が表示されるので、"setup/reset the DB"のリンクをクリックすると、
また下記の画面が表示されるので、OKをクリックすれば、Mutillidae用のデータベースが仮想マシンのMySQL上に構築されます。
HTTPS接続の有効化
デフォルトではMutillidaeとはHTTPで通信を行います。ただ、HTTPS通信に関する脆弱性などの勉強をしたいときにはHTTPSを有効化する必要があります。上記のVagrantfileでは、仮想マシン側でHTTPS通信が出来るようになる設定をしているので、MutillidaeアプリでもHTTPS通信をするように設定させます。
下記URLにアクセスして、
http://192.168.33.10/mutillidae/
下記画面のEnforce SSLをクリック。
自己証明書なので、下記のような警告画面が出ると思いますが、無視して先に進めます。(Chromeであれば、Proceed to 192.168.33.10 (unsafe)をクリック)
そうすると、HTTPSが有効になります。
OWASP Mutillidae IIの簡単な使い方
OWASP Top 10とは、ウェブサイトでよく見られる脆弱性のTop10を世界中のセキュリティの専門家がまとめて公表したものです。
Category:OWASP Top Ten Project - OWASP
数年ごとに内容を見直しているようで、OWASP Top 10(2010), OWASP Top 10(2013)などがあります。
例えば、OWASP Top 10(2017)のA1 - Injection(SQL)の内容を確認したい場合は、左側のメニューから順番に階層構造をたどって目的の脆弱性のデモ画面のリンクをクリックします。
このような感じで各機能の脆弱性を実際に自分の目で確かめながら確認することが出来ます。下記は、入力したHTMLタグ(br)がそのまま出力の際に処理されてしまっている例です。
How to Implement Nginx Client Certificate Authentication
When we need to collaborate with outside companies to manage web site's content, admin tool site is sometimes used. So admin tool has to be exposed on the Internet network. In this case password authentication function is often used to restrict other client's access. But Nginx can also use client certificate authentication function. So I would like to introduce client certificate implementation in this article.
client certificate authentication benefits
1. Nginx can deny irrelevant user's access.
2. Nginx can revoke issued client certificate at any time.
About 1, even if username and password is not leaked, hackers try to do a brute force attack indiscriminately. So password authentication might be broken someday. Client certificate authentication doesn't allow user access who doesn't have a client certificate. This feature makes the site more secure that is exposed to the Internet Network.
About 2, Nginx administrator can revoke the client certificate to deny admin tool access from unauthorized user when outside company's contract finishes.
How to implement client certificate authentication by Nginx
Nginx server side settings
Off course root user is used when configure Nginx settings. In this example Nginx is installed under "/usr/local/nginx" directory. Please adopt below instructions to your environment properly.
1. generate CA certificate and Key
mkdir -pv /usr/local/nginx/conf/client-certificates cd /usr/local/nginx/conf/client-certificates openssl genrsa -out ca.key 2048 # set proper certificate expiration date, in this example 2 years # set site's domain name on "CN" field openssl req -new -x509 -days 730 -key ca.key -out ca.crt -subj "/C=JP/ST=Tokyo/L=Ota-ku/O=Cat Inc./OU=Development/CN=tool.toripiyo.com/emailAddress=admin@toripiyo.com"
2. generate CRL
# configure CRL for revocation settings touch /etc/pki/CA/index.txt && echo '01' > /etc/pki/CA/crlnumber openssl ca -name CA_default -gencrl -keyfile ca.key -cert ca.crt -out ca.crl -crldays 730 diff -U0 <(openssl x509 -noout -modulus -in ca.crt) <(openssl rsa -noout -modulus -in ca.key)
3. generate client certificate for each user
# In this example "toripiyo" user's client certificate is generated # Please iterate this process as you require _CLIENTNAME='toripiyo' mkdir /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} cd /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} openssl genrsa -out ${_CLIENTNAME}.key 2048 openssl req -new -key ${_CLIENTNAME}.key -out ${_CLIENTNAME}.csr -subj "/C=JP/ST=Tokyo/L=Ota-ku/O=Cat Inc./OU=Development/CN=${_CLIENTNAME}/emailAddress=admin@toripiyo.com" openssl x509 -req -days 365 -in ${_CLIENTNAME}.csr -CA ../ca.crt -CAkey ../ca.key -CAcreateserial -CAserial ../ca.seq -out ${_CLIENTNAME}.crt # this command execution prompts the password input. don't forget the password. the password is used for client certificate registration openssl pkcs12 -export -clcerts -in ${_CLIENTNAME}.crt -inkey ${_CLIENTNAME}.key -out ${_CLIENTNAME}.p12 # set file permission to 640 chmod 640 ${_CLIENTNAME}.* ls -lta
4. configure Nginx settings
cd /usr/local/nginx/conf cp -ivp nginx.conf{,.$(date +%Y%m%d)} vi nginx.conf # add the following directives that are related to client authentication # - set clientcert log format # - ssl_verify_client on: enable client certificate authenticate. if client certificate is not shown, access is defied. ---------------------------------------------------------------------------------------------- log_format clientcert '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '$request_time $upstream_response_time ' '"$ssl_client_s_dn($ssl_client_serial)"'; ssl_client_certificate client-certificates/ca.crt; ssl_crl client-certificates/ca.crl; ssl_verify_client on; access_log logs/host.access.log clientcert; ----------------------------------------------------------------------------------------------
5. restart Nginx
# stop Nginx daemon ps aux | grep -i nginx /etc/init.d/nginx stop ps aux | grep -i nginx less /usr/local/nginx/logs/error.log # start Nginx daemon /etc/init.d/nginx start ps aux | grep -i nginx less /usr/local/nginx/logs/error.log
typical regular operations for Nginx client certificate management
issue new client certificate for new user
If new client(tama) joins our team, issue the new client certificate by following below procedure.
1. issue client certificate _CLIENTNAME='tama' mkdir /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} cd /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} openssl genrsa -out ${_CLIENTNAME}.key 2048 openssl req -new -key ${_CLIENTNAME}.key -out ${_CLIENTNAME}.csr -subj "/C=JP/ST=Tokyo/L=Ota-ku/O=Cat Inc./OU=Development/CN=${_CLIENTNAME}/emailAddress=admin@toripiyo.com" openssl x509 -req -days 365 -in ${_CLIENTNAME}.csr -CA ../ca.crt -CAkey ../ca.key -CAcreateserial -CAserial ../ca.seq -out ${_CLIENTNAME}.crt # password can be put on as a openssl option directly. "doraemon" is used as a password in this case openssl pkcs12 -password doraemon -export -clcerts -in ${_CLIENTNAME}.crt -inkey ${_CLIENTNAME}.key -out ${_CLIENTNAME}.p12 # set file permission to 640 chmod 640 ${_CLIENTNAME}.* ls -lta 2.Nginx restart is not required 3. Share new client certificate with new user
revoke specific client certificate
When tama leaves our team, following procedure makes the certificate to be revoked.
1. update index.txt _CLIENTNAME='tama' cd /usr/local/nginx/conf/client-certificates openssl ca -name CA_default \ -revoke ${_CLIENTNAME}/${_CLIENTNAME}.crt \ -keyfile ca.key \ -cert ca.crt 2. update ca.crl openssl ca -name CA_default -gencrl \ -keyfile ca.key \ -cert ca.crt \ -out ca.crl \ -crldays 730 3. restart nginx ps aux | grep -i nginx /etc/init.d/nginx stop ps aux | grep -i nginx less /usr/local/nginx/logs/error.log /etc/init.d/nginx start ps aux | grep -i nginx less /usr/local/nginx/logs/error.log
reactivate the revoked certificate
If tama withdraws team leaving, following procedure makes the certificate to be reactivated.
1. modify index.txt vi /etc/pki/CA/index.txt ==================== 1. change "R" => "V" on first column of corresponding certificate row 2. delete third column characters of corresponding certificate row (important: tabs between second and fourth colomn not to be deleted!! If not, openssl outputs error message.) ==================== 2. update ca.crl cd /usr/local/nginx/conf/client-certificates openssl ca -name CA_default -gencrl \ -keyfile ca.key \ -cert ca.crt \ -out ca.crl \ -crldays 730 3. restart nginx ps aux | grep -i nginx /etc/init.d/nginx stop ps aux | grep -i nginx less /usr/local/nginx/logs/error.log /etc/init.d/nginx start ps aux | grep -i nginx less /usr/local/nginx/logs/error.log
友達に会いにマレーシアまで旅行に行ってきた
ちょっと前、7月の上旬にマレーシアで働いている友達に会いに行ってきました。
訪れた場所は、クアラルンプールとペナン島です。いままで東南アジアはタイとカンボジアに行ったことがあるのですが、マレーシアは一番治安が良いように感じました。ただ、ボルネオ島の東側は海賊が出るそうなので、東側の島に行くときは注意が必要です。マレーシアにはマレー系と中国系とインド系の人がいて、日本に比べれば多民族国家です。ごはんもマレー料理、中華料理、インド料理のレストランがあります。(マレー料理のレストランではアルコールは飲めないそうです。間違えてマレー料理の店にアルコールを持ち込まないように気をつけましょう。)物価は日本の3分の1ぐらいだそうで、大変住みやすそうな国でした。Gacktが住むのも納得です。
気候
気候は年中夏の天気で、天気予報を見るといつも晴れときどき雷雨となっています。ただ気温は30度前後で、自分が滞在していたときは40度近い気温にはなりませんでした。友達はいつも夏なので服をあまり買わなくなったそうです。
シムフリー
いつも海外旅行ではシムフリーを利用しているのですが、マレーシアが一番手続きが簡単でした。KLIA2の空港に着いて入り口を出るとプリペイドシムフリーを販売している販売店がいくつもあります。自分はdigiという会社のシムフリーを買いました。値段はたしか500~800円で3GBぐらいあったと思います。旅行中ずっと使いましたが、ペナン島でも問題なくLTEを利用できました。ただ、マレーシアの通過のリンギットでないとシムフリーを購入できなかったので、まず空港内の両替所で日本円からリンギットに両替しましょう。マレーシアで両替したほうが日本よりも交換レートは良いそうです。
街中の移動方法
マレーシアにもUberはあるのですが、Grabというアプリがマレーシアでは一番はやっているそうです。友達は空港に行くときによく利用すると言っていました。運転手は様々で、普通のおじさんからものすごい若い見た目(中学生?に見えた)の人まで様々な人が運転手をしていました。現金払いもできるようで、友達はクレジットカード登録は怖いのでいつも現金払いをしていると言っていました。
クアラルンプールからペナン島への行き方
マレーシアで働く友達が事前にエアアジアの国内便を予約してくれていたので飛行機で行きました。KLIA2とペナン空港を往復でチケット代は5000円ほどです。飛行機に乗る時間自体は1時間弱なのですが、空港までの移動や空港での待ち時間を入れると合計5時間ぐらいはかかっている気がします。
マレーシアのたべもの
中国料理
- チャーシュー
初日の朝ごはんで行った中国料理店で食べたチャーシュー(?)はとても美味しかった。
一応、屋内だけど外と屋内を仕切る壁が全くなく、地元の人も朝から通っているようだった。
マレー料理
- ホテルの朝ごはん
マレー系の人が経営しているホテルにペナン島では泊まったので朝食のメインはマレー系料理です。ココナッツの汁でといたごはんは甘いのかと思っていたのですが、食べてみるとそんなに甘さは感じませんでした。
- ラクサ
マレーシアの麺料理ラクサ。ペナンの空港で食べました。麺が柔らかくて、酸っぱいスープは日本ではなかなか味わえないので、食べれば記憶に残ります。
【マレーシアソウルフード ヌードル編】 | マレーシアマガジン
インド料理
食べていない。。。。つぎ来たときは食べよう!
その他
- あんぱん
見た目はそれほど美味しそうに見えないけれど、個人的にはものすごくお薦めしたいあんぱん。30~40円ぐらいでスーパーで売られていて、日本のコンビニで売られているアンパンよりもちもちして柔らかくて美味しかった。
- 炭酸の入ったポカリスエット
日本では売られていない不思議な味がした。ポカリスエットに炭酸。これはこれで、ありかもしれない。
- ドリアン
噂どおり、においが強烈!!結局、現地で生のものを食べる勇気は持てなかった。
行った場所
- バトゥ洞窟
洞窟の中にあるお寺で、ヒンドゥー教の聖地だそうです。自分が訪れたときには洞窟内で工事が行われていました。洞窟内にある像の配色がとてもカラフルで、京都などのお寺にある仏像とは全然異なっていました。お土産物屋さんの商品もとてもカラフルです。
- バードパーク
クアラルンプールにある様々な種類の鳥を見ることができる施設です。入場料は1000円を超えてマレーシアにしてはちょっと高いですが、入ればいろんな種類の鳥を見ることが出来るので元は取ることが出来ると思います。この施設の中にはドクターフィッシュの出来る場所があって、日陰で休みながら魚に古い角質を食べてもらいました。ドクターフィッシュ自体の料金はそんな高くなかったと思います。
- ペナン島の夜の街並み
ちょうどペナン島に行ったときには夜にお祭りがやっていたようで、夜の街はたくさんの人で賑わっていました。人が多いので荷物には気をつけていたのですが、置き引きなどがいるようには感じませんでした。ストリートパフォーマンスをしている人や、いろんな露店があるので、食べながら夜の街並みを探検するのも楽しいです。
- ペナンプラナカンマンション
ペナン島にある昔の中国系の富豪の家を博物館として公開している場所です。華やかな暮らしを数々の装飾品から感じることが出来ます。自分もこんな家に住みたい。。。
おみやげ
- ドリアンチョコ
現地で生のドリアンを食べる機会はなかったので、空港の売店でベリーズのドリアンチョコを買いました。チョコになっているので少しドリアンの風味がするぐらいかなと思っていたのですが、強烈な匂いはチョコになっても健在ですw 自分は結局1個しか食べることが出来なくて、会社に持っていっても日本人はほとんど食べず中国人や台湾人の方が食べていました。次は普通のチョコを買おうと思います。
まだまだいろいろと食べてない料理や行ってない場所など、マレーシアにはたくさんあるので、友達が働いている間にまた行こうと思います。
nginxでクライアント証明書認証の設定と運用時に失効させる方法
WEBサイトの管理者ツールサイトを、例えば協力会社など外部の人にも操作してもらう必要があるときには、どうしてもインターネットに公開しないといけなくなることがあると思います。こういったとき、一般のユーザからのアクセスを拒否するためにユーザ名とパスワードで認証するように実装することが多いのですが、nginxではクライアント認証機能も利用できるのでその方法を紹介します。
クライアント認証にすると以下のメリットがあります
1. クライアント証明書を持っていないユーザに対してはログインを拒否できる
2. 証明書を失効できる
1について、ユーザ名・パスワードがたとえ漏洩していなくても、インターネット上からは絶えずブルートフォースアタックなどの攻撃を受けることになるので認証を突破される可能性があります。クライアント証明書認証ではクライアント証明書を持っている人しかログイン出来ないのでよりセキュアにインターネット上に管理ツールサイトを公開できます。
2について、協力会社との契約が終わった後に、証明書を失効することでクライアント証明書を持っていてもログインを拒否できるようになります。
nginxでのクライアント証明書認証の設定方法
サーバ側の設定
nginxのインストールされているサーバでrootユーザで実行します。nginxは/usr/local/nginxディレクトリの配下にインストールされている想定で進めます。自分の環境に合わせて適時修正してください。
1. CA証明書と鍵の作成
mkdir -pv /usr/local/nginx/conf/client-certificates cd /usr/local/nginx/conf/client-certificates openssl genrsa -out ca.key 2048 # 証明書の期限は適切に設定する、ここでは2年(730日)に設定している # CNには管理ツールサイトのドメイン名を記載する openssl req -new -x509 -days 730 -key ca.key -out ca.crt -subj "/C=JP/ST=Tokyo/L=Ota-ku/O=Cat Inc./OU=Development/CN=tool.toripiyo.com/emailAddress=admin@toripiyo.com"
2. CRLの作成
# クライアント証明書の失効に利用するのでCRLの設定をする touch /etc/pki/CA/index.txt && echo '01' > /etc/pki/CA/crlnumber openssl ca -name CA_default -gencrl -keyfile ca.key -cert ca.crt -out ca.crl -crldays 730 diff -U0 <(openssl x509 -noout -modulus -in ca.crt) <(openssl rsa -noout -modulus -in ca.key)
3. クライアント証明書をユーザ数分作成
# ここではtoripiyoというユーザのクライアント証明書を作成している _CLIENTNAME='toripiyo' mkdir /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} cd /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} openssl genrsa -out ${_CLIENTNAME}.key 2048 openssl req -new -key ${_CLIENTNAME}.key -out ${_CLIENTNAME}.csr -subj "/C=JP/ST=Tokyo/L=Ota-ku/O=Cat Inc./OU=Development/CN=${_CLIENTNAME}/emailAddress=admin@toripiyo.com" openssl x509 -req -days 365 -in ${_CLIENTNAME}.csr -CA ../ca.crt -CAkey ../ca.key -CAcreateserial -CAserial ../ca.seq -out ${_CLIENTNAME}.crt # 実行するとパスワードの入力を求められるので入力したパスワードを忘れないように注意! openssl pkcs12 -export -clcerts -in ${_CLIENTNAME}.crt -inkey ${_CLIENTNAME}.key -out ${_CLIENTNAME}.p12 # set file permission to 640 chmod 640 ${_CLIENTNAME}.* ls -lta
4. nginxの設定を変更
cd /usr/local/nginx/conf cp -ivp nginx.conf{,.$(date +%Y%m%d)} vi nginx.conf # client証明に関連した以下のdirectiveを追加する # - clientcertというログフォーマットを追加 # - ssl_verify_client on: クライアント認証する、証明書の提示がないとアクセス拒否 ---------------------------------------------------------------------------------------------- log_format clientcert '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '$request_time $upstream_response_time ' '"$ssl_client_s_dn($ssl_client_serial)"'; ssl_client_certificate client-certificates/ca.crt; ssl_crl client-certificates/ca.crl; ssl_verify_client on; access_log logs/host.access.log clientcert; ----------------------------------------------------------------------------------------------
5. nginxを再起動
# nginxを止める ps aux | grep -i nginx /etc/init.d/nginx stop ps aux | grep -i nginx less /usr/local/nginx/logs/error.log # nginxを開始する /etc/init.d/nginx start ps aux | grep -i nginx less /usr/local/nginx/logs/error.log
nginxでのクライアント証明書認証の運用で定常的に発生しそうな設定変更
新しいユーザ向けのクライアント証明書の新規発行方法
新しく管理ツールサイトを操作するtamaさんが入ってきたときは、以下のようにしてクライアント証明書を新規に発行します。
1. クライアント証明書を発行 _CLIENTNAME='tama' mkdir /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} cd /usr/local/nginx/conf/client-certificates/${_CLIENTNAME} openssl genrsa -out ${_CLIENTNAME}.key 2048 openssl req -new -key ${_CLIENTNAME}.key -out ${_CLIENTNAME}.csr -subj "/C=JP/ST=Tokyo/L=Ota-ku/O=Cat Inc./OU=Development/CN=${_CLIENTNAME}/emailAddress=admin@toripiyo.com" openssl x509 -req -days 365 -in ${_CLIENTNAME}.csr -CA ../ca.crt -CAkey ../ca.key -CAcreateserial -CAserial ../ca.seq -out ${_CLIENTNAME}.crt # パスワードを直接引数に指定することも可能。doraemonというパスワードを今回は指定している openssl pkcs12 -password doraemon -export -clcerts -in ${_CLIENTNAME}.crt -inkey ${_CLIENTNAME}.key -out ${_CLIENTNAME}.p12 # set file permission to 640 chmod 640 ${_CLIENTNAME}.* ls -lta 2. nginxの再起動は不要 3. クライアント証明書を配布するためにローカルPCに取得
特定のクライアント証明書の無効化方法
tamaさんが、管理ツールサイトを利用しなくなった場合は、以下のようにしてクライアント証明書を無効にさせます。
1. index.txt を更新する _CLIENTNAME='tama' cd /usr/local/nginx/conf/client-certificates openssl ca -name CA_default \ -revoke ${_CLIENTNAME}/${_CLIENTNAME}.crt \ -keyfile ca.key \ -cert ca.crt 2. ca.crl を更新する openssl ca -name CA_default -gencrl \ -keyfile ca.key \ -cert ca.crt \ -out ca.crl \ -crldays 730 3. nginxを再起動する ps aux | grep -i nginx /etc/init.d/nginx stop ps aux | grep -i nginx less /usr/local/nginx/logs/error.log /etc/init.d/nginx start ps aux | grep -i nginx less /usr/local/nginx/logs/error.log
無効化してしまった証明書を再び有効化する方法
tamaさんのクライアント証明書を無効にしたけれど、やっぱり管理ツールサイトを利用する必要がありクライアント証明書の再配布をしたくない場合は以下のようにします。
1. index.txtのファイルを編集 vi /etc/pki/CA/index.txt ==================== - 該当する行の最初の列の"R" と記載のある項目を "V" に変更 - 該当する行の3番目の列を削除 (2列目と4列目にあるカラムを残しておかないと次のopensslコマンドでエラーを出すので文字だけを消すようにすること。3番目の列は""となる。) ==================== 2. ca.crlを更新 cd /usr/local/nginx/conf/client-certificates openssl ca -name CA_default -gencrl \ -keyfile ca.key \ -cert ca.crt \ -out ca.crl \ -crldays 730 3. nginxを再起動する ps aux | grep -i nginx /etc/init.d/nginx stop ps aux | grep -i nginx less /usr/local/nginx/logs/error.log /etc/init.d/nginx start ps aux | grep -i nginx less /usr/local/nginx/logs/error.log
openvpnを使ってaws環境にVPNサーバを比較的低コストで構築する方法
追記
Amazon Linux 2 向けに新しく記事を書き直しました!
toripiyo.hatenablog.com
=============================================================
家のネットワークとAWS環境をVPNで繋ぎたくて、openvpnでVPN環境を構築してみました。いろんなサイトを参考にしながら構築しているので、その手順をまとめたいと思います。中小企業であれば、専用のVPN機器を購入しなくてもこれで十分ではないかと思います。VPNにかかるコストはt2.nanoの稼働コストのみなので、比較的安い費用でvpnを構築できます。
上図の構成の通り、VPNサーバをAWS環境上に構築します。この構成を取ることで、
- ユーザはVPNサーバを通してSSHやHTTP通信を行えるようになり、サービスを不必要に外部に公開しなくても良くなります。例えば、データベースサーバをMacなどから直接いじりたいときも、データベースサーバをインターネット環境に公開する必要はありません。
- ユーザ個別に証明書と鍵を発行することでプロジェクトから抜けたユーザがAWS環境にアクセス出来ないように個別にアクセス制御が出来ます。
このVPNサーバは、1個のVPCに1個構築するイメージで構築しています。ですので、複数のVPCでVPNサーバを利用したい場合は、VPNサーバを各VPCごとに構築する必要がありますのでお気をつけください。
VPN 環境の構築
VPNサーバの構築
VPNサーバ用のEC2インスタンスを起動
そんなに高いスペックでなくても、数人のユーザで利用するのであれば負荷はほとんどなく利用できます。
spec
- AMI:amzn-ami-hvm-2017.03.1.20170623-x86_64-gp2, SSD Volume Type
- Subnet: subnet1 (subnet1は、インターネットと通信できるようにInternet Gatewayがルーティングテーブルに設定されている必要がある。)
- instance type: t2.nano
- root volume: ebs
security groupを設定
以下のInbound設定をする
# vpn接続で利用するポート TCP/1194 # vpnサーバにsshログインして作業するために開ける、作業が終わったら閉じても構わない SSH/TCP/22
elastic IPを設定
VPNサーバのグローバルIPアドレスを固定するために、AWSのコンソールから設定する
日本時間に修正
clockファイルの修正
vi /etc/sysconfig/clock # ZONE="UTC" ZONE="Japan" UTC=true
シンボリックリンクの修正
ln -sf /usr/share/zoneinfo/Japan /etc/localtime
OS内のネットワーク設定の修正
ip forwardingの有効化
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -w net.ipv4.ip_forward=1 cat /proc/sys/net/ipv4/ip_forward # 1となっていることを確認
ip masqueradeの有効化
echo "iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE" >> /etc/rc.local (ip masqueradeの起動時の有効化)
openvpnのインストール
パッケージのアップデート
yum update -y
openvpnパッケージのインストール
yum install -y openvpn
easy-rsaパッケージのインストール
yum install easy-rsa -y --enablerepo=epel
証明書の作成
CA証明書と鍵の作成
cd /usr/share/easy-rsa/2.0 vi vars # 組織情報とあうように適切な値を入力する export KEY_COUNTRY="JP" export KEY_PROVINCE="Tokyo" export KEY_CITY="Ota-ku" export KEY_ORG="Cat Inc." export KEY_EMAIL="admin@toripiyo.com" export KEY_OU="Development Unit" . ./vars ./clean-all # "NOTE: If you run ./clean-all, I will be doing a rm -rf on /usr/share/easy-rsa/2.0/keys" message will be shown. ./build-ca # use default value
サーバ証明書と鍵の作成
./build-key-server server # set "common name" => vpn host name
クライアント証明書と鍵の作成
- プロンプトが表示されたときは、基本的にそのままEnterを押していけば大丈夫
- 下記では、tamaというユーザ向けのクライアント証明書と鍵を作成する例
./build-key tama
Diffie Hellmanパラメータの生成
# 少し生成に時間がかかる ./build-dh
証明書失効のための設定
- ダミー証明書を作成して失効する、一度実施しないと証明書失効リストファイルが作成されない
cd /usr/share/easy-rsa/2.0 . ./vars ./build-key dummy # use default value ./revoke-full dummy (keys/crl.pem ファイルが作成される)
openvpnサーバの設定
server.confファイルの編集
protoをudpにしているサイトが多いけれど、tcpに変更したほうが接続が安定したのでtcpにしている
sudo cp /usr/share/doc/openvpn-*/sample/sample-config-files/server.conf /etc/openvpn/ vi /etc/openvpn/server.conf # 以下の設定で上書きする port 1194 proto tcp dev tun ca /usr/share/easy-rsa/2.0/keys/ca.crt cert /usr/share/easy-rsa/2.0/keys/server.crt key /usr/share/easy-rsa/2.0/keys/server.key # This file should be kept a secret dh /usr/share/easy-rsa/2.0/keys/dh2048.pem server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "route 10.1.0.0 255.255.0.0" #VPC内部のプライベートIPレンジが10.1.0.0/16の場合 keepalive 10 120 comp-lzo max-clients 20 persist-key persist-tun status openvpn-status.log log-append /var/log/openvpn.log verb 3 crl-verify /usr/share/easy-rsa/2.0/keys/crl.pem
chkconfig openvpn on
openvpnサーバの起動
openvpn /etc/openvpn/server.conf
サーバ再起動
- サーバを再起動してもopenvpnは正常に稼働するか確認するためにサーバを再起動
reboot
VPNクライアントの設定
VPNサーバを構築できたらVPNに繋げるようにクライアント側の設定をする
tunnelbrickのインストール
homebrewのcaskを利用してインストール
brew cask install tunnelblick
証明書と鍵を入手
(ユーザ名).key, (ユーザ名).crt, ca.crtの3ファイルが必要になるのでVPNサーバからscpなどで取得しておく
client.confファイルの作成
- Macのhomeディレクトリの下に、.vpnというディレクトリを作成して、 (ユーザ名).key, (ユーザ名).crt, ca.crtの3ファイルを置く
- .vpnディレクトリの配下などで、client.confファイルを作成する(ファイル名は好きな名前に変更しても大丈夫)
- client.conf
client dev tun proto tcp remote (vpnサーバのグローバルIPアドレス) 1194 resolv-retry infinite nobind persist-key persist-tun ca (ca.crtのファイルパス) cert ((ユーザ名).crtのファイルパス) key ((ユーザ名).keyのファイルパス) remote-cert-tls server comp-lzo verb 3
tunnelbrickによる接続
- tunnelbrickを起動する
- client.confのファイルを画面右上のtunnelbrickのアイコンにドラッグアンドドロップする
- 表示されてきたプロンプト画面でOnly Meをクリックする
- Macのパスワード入力を求められるので入力する。これでVPNサーバとクライアントでコネクションを貼れるようになる。
VPNの運用
新しいクライアントの追加作業
新しくvpnを使うユーザが増えた場合は以下のように作業します。
生成された(新しいユーザ名) .crt, (新しいユーザ名) .key と ca.crtのファイルを新しいユーザに共有してあげてください。
cd /usr/share/easy-rsa/2.0 . ./vars ./build-key (新しいユーザ名) # use default value * openvpnの再起動は不要
既存のクライアントの削除作業
退職したなどの理由で、特定のユーザがvpnを使えないようにするには以下のように作業します。
cd /usr/share/easy-rsa/2.0 . ./vars ./revoke-full (削除するユーザ 名) (keys/crl.pem ファイルが作成される) * openvpnの再起動は不要
raspberry pi 3にclamavを導入する
最近、raspberry piのセキュリティが気になって色々と設定しているのですが、今回はclamavの設定を書きます。ドキュメントなど読むと、clamavには2種類の動かし方があるようです。
1. scanのときにプロセスを立ち上げる方法
2. デーモンを立ち上げておく方法
1の方法でファイルをscanするときは、clamscanコマンド。2の方法でファイルをscanするときは、clamdscanコマンドを利用します。この2種類のコマンドを比較すると、scanの速度に違いがありました。
(ちなみに、自分が見つけた中では公式のサイトのpdfドキュメントが一番詳しく記載されていました。https://github.com/vrtadmin/clamav-faq/raw/master/manual/clamdoc.pdf)
raspberry pi 3上で732個のファイル(ファイルの合計の大きさは2.4GB)のscanを比較した場合
clamscan: 3min19sec clamdscan: 2min9sec
デーモンを立ち上げていると、一定のメモリ量が常に消費されてしまいますが、scan時のパフォーマンスはデーモンモードのほうが良さそうです。一番避けたい設定はclamdをデーモンで立ち上げているのに、scanはclamscanで実行している場合です。こうすると、scan時にメモリを追加で消費することになってしまい、scanのスピードも遅くなります。
www.riscascape.net
clamavは、指定されたファイルをscanして、データベースに登録されたウイルス署名と一致したファイルがないかどうか確認します。ですので、ウイルス署名のデータベース情報は定期的に更新される必要があります。freshclamコマンドはインターネットから最新のウイルス署名情報を取得してくれます。freshclamにもデーモンモードがあり、デーモンで起動していると、定期的にウイルス署名情報を取得するようです。
以上を踏まえて、自分の場合は、以下のようにraspberry piにclamavを設定しました。これで、webコンテンツ以下のファイルに対して毎日深夜の時間帯にスキャンをかけ、virusが検知されたらslackに通知されるようになります。
1. install clamav
apt-get update apt-get install clamav clamav-daemon
2. update virus definition database
freshclam
3. create script file (hooks.slack.com のURLは適宜変更)
cd /root vi virusscan.sh ------------------------------------------------ #!/bin/bash PATH=/usr/bin:/bin # virus scan CLAMSCANTMP=`mktemp` TIME=`date` MESSAGE="Virus is detected!!: ${TIME}" clamdscan /var/www/html/data > $CLAMSCANTMP 2>&1 # report slack grep FOUND$ $CLAMSCANTMP && \ curl -X POST --data-urlencode 'payload={"channel": "#alerts", "username": "alerts", "text": "'"${MESSAGE}"'", "icon_emoji": ":dog:"}' https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXX rm -f $CLAMSCANTMP ------------------------------------------------ chmod 700 virusscan.sh
4. set cron job
crontab -e ------------------------------------------------ 00 04 * * * sh /root/virusscan.sh ------------------------------------------------
ドキュメントを読むと、以下のコマンドがあったのでメモも兼ねて記載しておきます。
clamconf
- clamavの設定情報を表示する
root@raspberrypi:~# clamconf | head Checking configuration files in /etc/clamav Config file: clamd.conf ----------------------- LogFile = "/var/log/clamav/clamav.log" StatsHostID = "auto" StatsEnabled disabled StatsPEDisabled = "yes" StatsTimeout = "10" LogFileUnlock disabled
clamtop
- clamav用のtopコマンド
ClamdTOP version 0.99.2 Mon Jul 17 23:41:19 2017 NO CONNTIME LIV IDL QUEUE MAXQ MEM HOST ENGINE DBVER DBTIME 1 00:00:14 1 0 0 0 471M local 0.99.2 23571 2017-07-17 17h Details for Clamd version: ClamAV 0.99.2/23571/Mon Jul 17 17:08:59 2017 Primary threads: live 1 idle 0 max 12 ┌───────────────────────────────────────┐ [||| ] │Mem: heap 1M mmap 0M unused 0M│ Queue: 0 items 0 max │Libc: used 1M free 0M total 1M│ [ ] │Pool: count 1 used 470M total 470M│ │[||||||||||||||||||||||||||||||||||||] │ └───────────────────────────────────────
dockerコンテナのrailsコンソールで日本語入力をコンテナ再ビルドなしで出来るようにする方法
日本語がdockerコンテナのrailsコンソール上で入力できないので調べてみると、
以下のようにbuildし直すと出来るようになると記事がありました。
http://qiita.com/suin/items/856bf782d0d295352e51
ただ、再ビルドするのも面倒なので、
以下のようにrailsコンソールの実行時にenvで環境変数を指定することで日本語入力出来るようになりました。
root@b2de32d57cf1:/app# env LANG=C.UTF-8 rails c Running via Spring preloader in process 104 Loading development environment (Rails 5.0.0.1) irb(main):001:0> a = "日本語が入力できる!!" => "日本語が入力できる!!"