A little bit of everything

情報系大学院生の備忘録

RubyでTwitterのBotを作ってみた(前編)

Rubytter という RubyTwitter APIbot を作る。

※以下はrubyとgemが入っていることが前提
OS X 10.9.5 を使用


まずはRubytterのインストール

$ sudo gem install rubytter
Password:
Fetching: oauth-0.4.7.gem (100%)
Successfully installed oauth-0.4.7
Fetching: rubytter-1.5.1.gem (100%)
Successfully installed rubytter-1.5.1
Parsing documentation for oauth-0.4.7
Installing ri documentation for oauth-0.4.7
Parsing documentation for rubytter-1.5.1
Installing ri documentation for rubytter-1.5.1
2 gems installed


まず、index.rbというファイルを作って、次のようなプログラムを書いた。

require 'rubygems'
require 'rubytter'

client = Rubytter.new('username', 'passwd')  #適宜変更
client.update("test")  #こうやって書くと投稿できる

↑を実行したら怒られた。↓みたいな感じで。

$ ruby index.rb 
/Library/Ruby/Gems/2.0.0/gems/rubytter-1.5.1/lib/rubytter.rb:231:in `http_request': Rubytter::APIError (Rubytter::APIError)
    from /Library/Ruby/Gems/2.0.0/gems/rubytter-1.5.1/lib/rubytter.rb:167:in `post'
    from (eval):2:in `update_status'
    from /Library/Ruby/Gems/2.0.0/gems/rubytter-1.5.1/lib/rubytter.rb:138:in `update_status'
    from /Library/Ruby/Gems/2.0.0/gems/rubytter-1.5.1/lib/rubytter.rb:148:in `update'
    from index.rb:10:in `<main>'

今のコードはBASIC認証を使っているが、調べてみたらOAuthでやんなきゃいけないらしい。BASIC認証は廃止されたみたい。

www.itmedia.co.jp


ということで、OAuthをinstall
(ちなみに、OAuthを使うと、投稿した際に表示される投稿元クライアント名を自由に設定できるらしい。)

$ sudo gem install oauth
Successfully installed oauth-0.4.7
Parsing documentation for oauth-0.4.7
1 gem installed


次にOAuthクライアントを登録する。まずはOAuthに登録したいTwitterアカウントに、Webからログインしておく。 ログインした状態で、 Twitter Application Management にアクセスして登録。

Access level は Read and write にしておけばOK(Readだけだと投稿できない)
Keys and Access Tokes タブに移動し、"Consumer key"と"Consumer secret"をメモする。
Create My Access Tokenをクリックし、”Access Token”と"Access Token Secret"をメモする。

RubyTwitterライブラリをインストール

$ sudo gem install twitter
(以下略)

ここ rubyでtwitterのbotを実装する(第5世代のやり方) - Qiita を参考に、↓のようなプログラムを作る。

# coding: utf-8
require "twitter"
require "oauth"

client = Twitter::REST::Client.new do |config|
  config.consumer_key = "XXXXXX"
  config.consumer_secret = "YYYYYY"
  config.access_token        = "ZZZZZZ"
  config.access_token_secret = "XYZXYZ"
end

client.update("Hello World from Ruby!")


これを実行すれば、

$ ruby index.rb 

ひとまずPOSTができるプログラムはOK!

後半へ続く

su で root になれるユーザを限定する

ユーザが複数いる場合、全員がroot になれてしまうと、セキュリティ的によろしくない。そこで、root になれるユーザを限定する。

これは、/etc/pam.d/su の中身を変更すればできる。

#
# The PAM configuration file for the Shadow `su' service
#

# This allows root to su without passwords (normal operation)
auth       sufficient pam_rootok.so

# Uncomment this to force users to be a member of group root
# before they can use `su'. You can also add "group=foo"
# to the end of this line if you want to use a group other
# than the default "root" (but this may have side effect of
# denying "root" user, unless she's a member of "foo" or explicitly
# permitted earlier by e.g. "sufficient pam_rootok.so").
# (Replaces the `SU_WHEEL_ONLY' option from login.defs)
# auth       required   pam_wheel.so   ←ここのコメントをはずす

(略)

コメントをはずそう。

#
# The PAM configuration file for the Shadow `su' service
#

# This allows root to su without passwords (normal operation)
auth       sufficient pam_rootok.so

# Uncomment this to force users to be a member of group root
# before they can use `su'. You can also add "group=foo"
# to the end of this line if you want to use a group other
# than the default "root" (but this may have side effect of
# denying "root" user, unless she's a member of "foo" or explicitly
# permitted earlier by e.g. "sufficient pam_rootok.so").
# (Replaces the `SU_WHEEL_ONLY' option from login.defs)
auth       required   pam_wheel.so   ←こうね。

(略)

そうするとwheelグループの人しかsuできないようになる。

自分の場合はwheelグループがデフォルトで存在しなかったので、作った。
groupadd wheel
で、suを使えるようにしたいユーザをwheelに入れる。
usermod -G wheel user01
(ちなみに -G オプションはPrimary Group以外のグループ変更をするときに使う。Primary Group変更 は小文字の -g オプション。)
これでuser01はwheelグループに入ったので、suを使えるようになる。

すでにwheelみたいな役割のグループが存在している場合

すでにwheelみたいな役割のグループが存在しているなら、そのグループに所属する人に対してのみsuを許可するようにできる。その場合は、/etc/pam.d/su の中身で、

auth required pam_wheel.so

の後ろに「group=グループ名」を追加する。

#
# The PAM configuration file for the Shadow `su' service
#

# This allows root to su without passwords (normal operation)
auth       sufficient pam_rootok.so

# Uncomment this to force users to be a member of group root
# before they can use `su'. You can also add "group=foo"
# to the end of this line if you want to use a group other
# than the default "root" (but this may have side effect of
# denying "root" user, unless she's a member of "foo" or explicitly
# permitted earlier by e.g. "sufficient pam_rootok.so").
# (Replaces the `SU_WHEEL_ONLY' option from login.defs)
auth       required   pam_wheel.so group=group01  ←こんなかんじで。

(略)

こうすると、wheelの代わりにgroup01に所属しているユーザが、suが使えるようになる。

apache2でindex.htmlが無いときにディレクトリの中身を見せない設定

ブラウザでWebサーバのURLを打つとき、http://〜〜〜.html というように具体的なファイルを指定するのではなく、ディレクトリ名でアクセスした場合、デフォルトでは index.html をGETすることになっている。
つまり、サーバ側に index.html がないと、エラーになってしまう。エラーの際に、サーバの指定したディレクトリの中身が見えてしまう。これはセキュリティ的によくない。


そこで、index.html がない場合でも、ディレクトリの他のファイルが見えないような設定にする。設定ファイルは /etc/httpd/conf/httpd.conf とかに全部書かれているんじゃなく、/etc/apache2/ に複数ある。

/etc/apache2/sites-available/default の

<Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
</Directory>

という部分の、

Options Indexes FollowSymLinks MultiViews

の行を、

Options -Indexes FollowSymLinks MultiViews

とする。わかりにくいけど、"Indexes" を "-Indexes" と変更している。

こうすると、index.htmlがなくてもディレクトリの中身が見られなくなる。

【Java】匿名クラスから親のクラスを参照する方法

親クラス名.this でアクセス可能。

class A{
    private int i = 0;

    public A(){
        Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
                //something 
                A.this.i++;           // ← 親クラスAのthisにアクセスしている
            });
        t.start();
    }
}

【Java】Swing でのコンポネント追加後に表示されない

swingのコンポーネントが表示されない − Java Solution − @IT

【Java】スレッドが死ぬタイミング

start() で起動したスレッドは、run が終了すると消滅する。

へー。

MySQL で /var/lib/mysql/mysql.sock に繋げないエラー

mysql -u rootMySQLを起動しようとしたときに出るこんなエラー。

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'

/var/lib/mysql/mysql.sock に繋げないと言っているので、
ls -a /var/lib/mysql/
mysql.sockがあるか確認する。

無かったので、作ってみた。権限も変更しておく。
sudo touch /var/lib/mysql/mysql.sock
sudo chown mysql:mysql /var/lib/mysql

そして MySQL再起動
sudo /etc/init.d/mysqld restart

なんとこれだけで動いた!