ストックドッグ

KatoTakahiro。金融系の会社で働くSEが株やPython、その他諸々について書いています。サービスも運営してます→http://fmbrain.work

conoha(VPS)にanacondaを利用してpython3をインストール

conoha(VPS)にanacondaを利用して、pythonの環境を整えました。

最近、ちょっとしたメモ系の記事が多いです、そして今回も。


Anacondaをローカル環境にダウンロード
Download Anaconda Now! | Continuum


2秒だけ悩んだのは、どうやってconohaにanacondaの元ソースをダウンロードするかです。

gitでcloneするか、あるいはいったんローカル環境に持って行って、ローカル環境からVPSにファイルを転送するか。

ローカル環境からVPSにファイルを転送する方を選択

scp Anaconda3-4.3.1-Linux-x86_64.sh ubuntu@157.***.***.***:/home/user

scpはリモートとローカル間でコピーするためのコマンドです。

転送が成功したので。

インストーラーを起動

bash Anaconda3-4.3.1-Linux-x86_64.sh

適当にenterとyesを繰り返すと、conohaに無事anacondaの環境が入りました。

以上、終わり。

ufwでファイアーウォールを構築

ファイアーウォールを設定する

conohaでVPSを借りたので、ファイアーウォールを設定します。

今のところガバガバセキュリティなのでよくありません。

ufwで設定

ufwは、Ubuntuのファイアーウォールを設定するためのツールです。

このコマンドでufwの状態を確認する。

#状態を確認
sudo ufw status

statusで現在開いているポートを確認できます。

このコマンドでファイアーウォールを有効化します。

#有効化
sudo ufw enable


初期設定では全てのポートを遮断します。

とりあえず全てのポートを遮断してから、開くポートだけを許可していきます。

#全てのポートを遮断
sudo ufw default DENY


httpsとhttpからの接続を許可する。

ポートを指定することもできるので、httpであればポート番号80、httpsであればポート番号443としても可。

#https接続を許可
sudo ufw allow https/tcp
sudo ufw allow http/tcp

#ポートを直接指定することも可能
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp


ssh接続も許可。

ブルートフォースアタックが怖かったら、接続にリミットをかける。

#ssh接続を許可
sudo ufw allow ssh

#limitを設定
sudo ufw limit ssh

まとめ

ufwで簡単にファイアーウォールを設定できました。

Ubuntuからconoha(VPS)にSSH接続してみる

苦労したよ

SSH接続、けっこう詰まったので自分なりにまとめておきます。

あと、conohaのサイトは案外サラッとしか書いていないので、自分なりにではありますが設定を行う理由なんかも書いて詳しめの記事にしています。

間違っていたらすみません。笑

SSH接続をする理由

conohaはサイト上からコンソールを開けるので、とても便利です。

しかし、いちいちconohaのサイトに行ってコンソールを開いて...ってやるのは面倒なので、自分のPC(クライアント)からconohaのVPSをリモート操作しましょう。

っていう導入的な部分は他のサイトにたくさん書いてあるので、さっさと本題に行きます。

まずはパスワード認証でSSH接続

SSH接続には2つの接続方法があります。

  • パスワード認証方式
  • 公開鍵認証方式

パスワード認証方式は、セキュリティの面から推奨されていません。(後に後述)

まずはパスワード認証によるSSH接続を行い、後でパスワード認証から公開鍵認証に変更します。


まずはrootでVPSにログインします。

そして、sshd_configを設定を変更します。

sshd_configにssh接続に関する設定が記述してあります。

ここで2つの設定を変更します。

vi /etc/ssh/sshd_config
  • PasswordAuthentication no → yes
  • ChallengeResponseAuthentication no → yes

この2つをnoからyesに変更します。

私の乏しい知識でこの2つの設定の意味を説明すると、パスワード認証を許可するか否かです。

PasswordAuthenticationはパスワード認証の許可、ChallengeResponseAuthenticationはパスワードを送った際にログイン成功か失敗かを示すためのものです。

基本的にサーバーは、ブルートフォースアタック(何通りものパスワードを送りつけてログインを試みる力技攻撃)を避けるためにパスワード認証は許可しません。

そのため、これら2つはデフォルトでnoになっています。

SSH接続を行うために一時的にyesにするだけなので、後でnoに変更します。

2つともnoに変更したら。

service sshd restart

sshd_configの変更を反映。


これでクライアントPCからSSH接続を試みると成功するはずです。

ssh root@157.7*******

公開鍵方式でSSH接続

VPS側のホームディレクトリにいきます。

#cdでホームディレクトリに移動
cd

このホームディレクトリに公開鍵を入れるフォルダを作ります。

たしかubuntuにはデフォルトでなかったで、私は自分で作ったのですが、すでにあれば作る必要はありません。

#公開鍵をいれるフォルダがあるかを確認
#オプション-aで隠しファイルも表示される
ls -a

そこに.sshというフォルダがなければ。

mkdir .ssh

次に、この.sshフォルダに書き込み、読み込み、実行の権限を与えます。

chmod 700 /root/.ssh/

ここで先ほどいじったsshd_configをもう一度いじり直しにいきます。

vi /etc/ssh/sshd_config

設定を変更するのは公開鍵認証を許可するためです。

#RSA鍵を許可
RSAAuthentication yes

#公開鍵認証を許可
PubkeyAuthentication yes

#公開鍵の場所をここで明示
AuthorizedKeysFile      .ssh/authorized_keys


以上の作業が終わったら、ここからクライアントPCに戻ります。

#クライアントPCの.sshフォルダに移ります
ls -a
cd .ssh

ここで秘密鍵と公開鍵を生成します。

ssh-keygen -t rsa -b 2048

ssh-keygenはSSHで利用する認証用の鍵を生成・管理・変換するコマンドです。

鍵のタイプはRSA、2048bitの鍵を生成します。

生成時にパスフレーズを要求されますが、全てデフォルトでかまわないので、全部Enterで問題ないと思います。

生成されるid_rsa秘密鍵、これは絶対にばらしちゃいけないので大切にPCに保管しておきます。

id_rsa.pubは公開鍵で、こちらをVPS側にアップロードします。

そして、公開鍵に読み書きの権限を付与します。

chmod 600 ~/.ssh/id_rsa.pub

そして、VPS側に送ります。

scp id_rsa.pub root@157.7*******:/root/.ssh/authorized_keys

scpはリモートとクライアント間でファイルをコピーするためのコマンドです。

今回はid_rsa.pubをauthorized_keysという名前に変えてVPSにコピーしています。

authorized_keysというファイル名は伝統のようです。


これで公開鍵認証方式でのSSH接続が可能になるはずです。

ssh root@157.7*******

パスワードなしで接続されれば、成功です。

逆にパスワードを要求されれば、失敗です。

root以外でのユーザーでSSH接続を行う

rootで接続を許可してしまうのは、なかなかまずいです。

もし、サーバーを乗っ取られた場合rootだと何でもできてしまうからです。

なので、SSH接続はroot以外のユーザーで行う必要があります。

VPS側でユーザーを追加し、これまでと同じ手順で公開鍵認証方式でのSSH接続を設定します。

ユーザーの追加。

#ユーザー追加
adduser user_name

#追加したユーザーがsudoコマンドを使えるようにする
gpasswd -a user_name sudo

ここまでやったら、あとはrootでの手順と同じなので省略。

ただ、公開鍵を送るときに気をつけたいのは。

scp id_rsa.pub root@157.7*******:~/.ssh/authorized_keys

ではなく、

scp id_rsa.pub root@157.7*******:/home/user_name/.ssh/authorized_keys

と、user_nameのフォルダに送ることをしっかりと記述しないといけません。

前者だとrootのほうのフォルダに送られてしまいます。

私はこのミスに気づくのにかなり時間を費やしました...笑

最後にrootでのログインとパスワード認証を禁止する

#パスワード認証の禁止
PasswordAuthentication no
ChallengeResponseAuthentication no

#rootでのログイン禁止
PermitRootLogin no

設定し終わったら、

service sshd restart

これで設定が反映されたはず。

rootでのログインはできなくなっています。

まとめ

conohaはさくらVPSより安くて良いのですが、さくらVPSと比べると情報量はどうしても劣りますね。

とくに私のようにはじめてVPSを使用する人からすると、エラーでたときにかなり困りました。

日本のサービスなので海外サイトにものっていませんし。

なので、私のようなVPS初心者のかたがconohaを使った時のためにけっこう詳しめに書きました。

(エラーがでまくったので、その都度調べるたびに勝手に詳しくなってしまった感はあるが)

誰かの助けになれば幸いですね。

以上終わり!

seleniumの環境構築と簡単な使い方

今は日曜日の夜2時

早く寝ないと!!

明日は仕事なんです。

急いで書くのでぶっきらぼうな今日は文章になるかもです。

何とかブログだけ書いてさっさと寝ます。

環境構築

pipでインストール可能です。

pip install selenium

seleniumAPIを通じてブラウザを使用するため、seleniumとは別にブラウザ用のドライバーをインストールする必要があります。

sites.google.com

SafariFirefoxChrome、Edge、どれでも好きなブラウザのドライバーの圧縮ファイルをHPからダウンロードでき、私はChromeを選択しました。

ダウンロードした圧縮ファイルを解凍するとChromedriverというファイルが現れます。

これをseleniumを使用するファイルと同じフォルダに入れておきます。


公式HPにはPATHを通すと書いてあったが、そこは本人の自由。

私は面倒だったので、そのままコードの中にChromedriverの位置を書きました。


ここらへんの環境構築にちょっと苦労しました。

Youtubeで「YUI」と検索する操作をseleniumを使ってやってみる

#unittestは単体テスト用のライブラリ。
#動作の開始から終了までの時間を計測してくれるので、なんとなく使用。
import unittest

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


class PythonOrgSearch(unittest.TestCase):

	def setUp(self):
		#pwdでカレントディレクトリを確認。
		#カレントディレクトリの場所をそのまま記述。
		#seleniumを実行するファイルとChromedriverを同じ場所に格納が楽。
		self.driver = webdriver.Chrome("/home/ubuntu/serv/robo/chromedriver")


	def test_serch_in_python_org(self):
		driver = self.driver
		#youtubeのURL
		#driverの中にはサイトの構造がHTMLとして格納されている。
		driver.get("https://www.youtube.com/")

		#youtubeの検索バーはid="masthead-search-term"
		#find_element_by_idで検索バーのidを取得してくる
		elem = driver.find_element_by_id("masthead-search-term")

		#yuiと検索
		elem.send_keys("yui", Keys.RETURN)

	def tearDown(self):
		self.driver.close()


if __name__ == "__main__":
    unittest.main()


ちなみに、youtubeのサイト構造の画像。
id="masthead-search-term"が検索バーであることがわかります。

f:id:doz13189:20170424023003p:plain

クリックもできるselenium

クリックを自動で行いときは.click()で可能。

方法はだいたいさっきと同じで、HTMLからクリックしたい要素のidを探して.click()をつけたします。

driver.find_element_by_id("about").click()

公式サイトを見るとドラッグ・アンド・ドロップもできるみたいだが、どの場面でドラッグ・アンド・ドロップを使うのかは私には思いつかない...

id要素以外の見つけ方

  • find_element_by_id
  • find_element_by_name
  • find_element_by_xpath
  • find_element_by_link_text
  • find_element_by_partial_link_text
  • find_element_by_tag_name
  • find_element_by_class_name
  • find_element_by_css_selector

案外たくさんある...

個人的にはclass_nameとidがあれば90%の作業はすむと思っています。

けっこう簡単だったselenium

思いの外使いやすかったです。

使い方自体もシンプル。

そして、汎用性抜群。

もうしばらく触ってみます。

隠しファイルの見方

ドット(.)から始まるファイルは通常、lsコマンドをうっても表示することは出来ません。

ls

ドットから始まるファイルは隠しファイルと呼ばれ、例えば環境変数を格納するために使ったりする.bashrcなどがあります。

これらを表示するにはlsコマンドにオプションをつけて、うつことで隠しファイルを表示することが出来ます。

ls -la

以上、終わり

herokuにルート権限はあるのか?

4月からはもっぱらherokuにつきっきりです。

ようやくherokuの全貌をつかめてきた感覚があり、前は読んでもわからなかった記事も少しづつではありますが、理解できるようになってきたところです。

今までローカルで動かしていたプログラムを自動プログラムに書き換えて、Webアプリで提供するという夢があと一歩のところまで来ました。

長かったです。

4月に入社して飲み会ラッシュの中、同期にはちょっとづつ飲み会苦手キャラを浸透させつつ、飲み会を断りやすい雰囲気を作って、5時に帰れる日は直帰してプログラムを書いて...

苦労に苦労を重ね、そして、大きな問題が発生しました。

まずはじめにroot権限とは?

ubuntuユーザはpip install ライブラリ を行う際、たいていsudoをつけます。

sudoというのはルート権限であることの宣言であり、sudoをつけることでファイルの書き込み・変更等を許可することになります。

ライブラリによってはファイルの書き換えを行う必要があるので、sudoをつけなければ、ファイルの書き込みができません的なエラーを発生させる要因になります。

たしか、windowsでは、コマンドプロンプト自体を起動する際にroot権限で起動するか否かを選択したはずです。

ここらへんの違いは設計思想の違いなんですかね。

herokuにroot権限はあるのか?

herokuはIaas系のサービスで、のせるOSは自由に選べます。(toolbeltという形で選択が可能です)

私はherokuにはUbuntuの環境を構築したのですが、なぜかheroku上でsudoコマンドが使用できません。


これが何を意味するかというと、ファイルを書き換えるライブラリがインストールできない、ということです。


これは詰みです。

本来、herokuからインストールできないライブラリ等はbuildpacksによってソースから直接インストールすれば良いのですが(私の解釈が間違ってなければ)、

今回はインストールできないわけではなくて、heroku上で動かすにはファイルを書き換える必要がある、ということなのでbuildpacksでは解決できません。


3日かけて(貴重な土日と5時帰りの月曜の夜)色々とgoogleで解決方法を探しまわったのですが、無理でした。

普通に考えてIaasでroot権限がないって考えにくいなぁと思いつつ、ただ自分では解決できないので諦めることにしました。

ただ一つ、良いことがあるとすれば、このエラーを餌に同期の中からプログラミング好きな人をたくさん見つけれたことです。

「プログラミング得意!?このエラーでてるねんけど、わかる?教えて!」みたいなノリで声をかけまくりました。

違うサービスを使しかないか...

仕方がないです。ドキュメントたくさん読んで、色々できるなぁなんて妄想していましたが...

プログラミングをはじめてそろそろ1年たつのですが、ガチで解決できないエラーに出会ったのはこれがはじめてでした。

この出会い一生忘れないと思います。


次のサービスの候補としては、AWSGoogleのやつ、さくらのVPS、conoho、このあたりです。

conohoは全く存在を知らなくて、同期の人に教えてもらいました。

今日の夜あたりからちょっとづつ調べながら次の移転先を探してみます。

以上、終わり。

herokuのタイムゾーンを変更したらAPSchedulerが動いた話

APSchedulerがピクリともしない問題発生

APSchedulerをcron式タイムスケジュールで0:20に命令を実行したいのですが、なぜか0:20になってもピクリともしませんでした。

from apscheduler.schedulers.blocking import BlockingScheduler

sched = BlockingScheduler()

#0:20
@sched.scheduled_job('cron', hour=0, minute=20)
def scheduled_job():
    print('This job is run every weekday at 0:20.')

sched.start()

時間設定の仕方はhour=0、minute=20で0:20を指すはずだが...

APChedulerをcron形式で動かすドキュメントを読んだので、きっと間違いはないはず。

apscheduler.triggers.cron — APScheduler 3.3.1.post4 documentation

だが、動かぬ。

タイムゾーンを変更していなかった

herokuのログを見るたびにいつも時間がずれてるなぁ、これどこの時間なんや、と思いつつ放置していたのですが、それが原因でした。

タイムゾーンUTCでした。

ということで。

herokuのタイムゾーンJSTに変更

まず、herokuの現在のタイムゾーンを念の為確認。

#heroku上でbashを起動してから。
heroku run bash

#タイムゾーンを確認
date

UTCだったので、タイムゾーンJSTに変更。

heroku config:add TZ=Asia/Tokyo

TZ=Asia/Tokyoという環境変数を追加して、設定を変更。

無事解決しました

最近は株価の分析には時間が割けてなくて、heroku上でシステムを動かすことにばかり時間を費やしています。

あまり楽しくはありませんが、これから自分一人でシステムを作っていこうと思うと避けて通れない道だと思っています。

なので、焦らず地道にドキュメントを読みながら作業を進めています。