ぬまのそこ

namazuのゆるいエンジニアブログ

Linuxのパーミッションで4桁のときの最初の0

今日したこと

  • windows10のVagrantVirtualBox)が上手く動かなくなっててBIOSが開けなかったり、設定項目にたどり着けなくておこになった。
  • なんかつかれたのでお風呂に行ってた。
  • vagrantで沢山VM上げてプロビジョニングして楽しんだ

Linuxパーミッションの数字表記

chmod 0644 ... とか よく書くじゃないですか。 この最初の0について。 気になったので調べてたら、これのことだったのねってなったのでメモ。

この最初の桁は0,1,2,4が使えて、それぞれ以下の意味になる

  • 0 とくになにもなし
  • 1 スティッキービット: 所有者以外消せないけど誰でも書き込めるって奴。 /tmpとかのディレクトリに初期設定されてる。ファイルに付与したら何も起きない。
  • 2 SGID: 付けた場合、そのファイルの所属グループの権限で動くようになる。
  • 4 SUID: 付けた場合、そのファイルの所有者の権限で動くようになる。

詳細は

qiita.com

このへん。

RackとかRailsでリダイレクトとかがhttpsにならないとき

今日したこと

  • いろいろ

短文技術エントリは手抜き。

nginx => railsとかでhttpsをraislに飛ばすときに解く

よくある構成だとおもう。 フロントのWebサーバまではHTTPSで飛ばして、最後のRailsにはHTTPでReverseProxyするってやつ。

そのときにHTTPヘッダをちゃんとNginxで設定しないとRails側がHTTPSで来た通信だということを認識しなくてうまく動かないのはよく知られた話。 X_Forwared_Proto htttps; とかはちゃんと書こうなって記事に引っかかる。

で。 これで引っかかった。 ちゃんと書いていたのにHTTPSと認識されなかったのは謎。

今回の問題は、 GoogleOmniauthのリダイレクトURLが何故かHTTPになってしまうということ。

コードを漁っていったら、Rackのschemeからhttpsかhttpかを取得していた。

このschemeの部分を見ていたらRails(Rack)がHTTPSできた通信かHTTP出来た通信か調べてるのがわかった。

def scheme
        if get_header(HTTPS) == 'on'
          'https'
        elsif get_header(HTTP_X_FORWARDED_SSL) == 'on'
          'https'
        elsif get_header(HTTP_X_FORWARDED_SCHEME)
          get_header(HTTP_X_FORWARDED_SCHEME)
        elsif get_header(HTTP_X_FORWARDED_PROTO)
          get_header(HTTP_X_FORWARDED_PROTO).split(',')[0]
        else
          get_header(RACK_URL_SCHEME)
        end
end

Rack schmeのここの部分だった。 これでhttpsか判断してるっぽい。 X_FORWARDED_PROTOなどなんかうまくいかなかったので、このコードにしたがって、Nginxで。。。

proxy_add_header X_FORWARDED_SSL on;

みたいにやったら、HTTPSと認識してくれて良しなに動いた。

どうでもいいはなし

  • 某所の電源がぶつぶつ切れる問題。 接続しているUPSのバッテリー切れが原因っぽかった。 対応したのでこれでいけるといいにゃぁ。
  • ストロングゼロ2本だと飛べないのでつらいね。

Ruby YAMLファイルを読み込んでメソッドで値を取れるクラス

今日したこと

にゃーん って感じ。 カルシウム足りないんじゃないのってくらい情緒不安定だった。

愚痴ってもしょうがないので、さっきちょっと作ったコードを載せて今日はおわり。

やりたかったこと

env1:
  obj1: hello
  obj2:
    obj2_1: hello
    obj2_2: hello
env2:
  obj1: hello

こんなconfi.ymlみたいなのがある。 一番大本が環境毎。 そのしたにyaml

これを

config = Config.new('env1')
config.obj1 #=> 'hello'
config.obj2.obj2_1 #=> 'hello'

みたいに使いたかった。 

これをやるGemは当然既にあるだろうし、いつもはEasySettingsっていうGemを使っている。 ただせっかくだし自前でちょろっとつくった。たいした用途ではなかったしね。

とりあえず思いついたのがこれ。 メソッド名で出すからハイフンが使えなかったり色々あるけど。

require 'yaml'

class Config
  CONFIG_FILE_NAME = './config.yml'

  def initialize(env)
    config = YAML.load_file(CONFIG_FILE_NAME)
    hash_method_define = Proc.new do |res, obj|
      obj.each do |k, v|
        if(v.kind_of?(Hash))
          res_child = Object.new
          hash_method_define.call(res_child, v)
          res.define_singleton_method(k) { res_child }
        else
          res.define_singleton_method(k) { v }
        end
      end
    end
    hash_method_define.call(self, config[env])
  end
end

Rubyってすごいんですね。

どうでもいいはなし

にゃー。 あした大学行きたくない。 

RSpecでFileIOをスタブにする

今日したこと

  • テスト書いたり諸々

単体テスト、疲れたときに書くと意外と良いかもしれない。 今日は其の途中で得た知見を書いてお茶を濁す

FileIOをする処理をRSpec

テスト対象

def file_write
  File.open('hoge.txt', 'w') do |f|
    f.print 'fuga'
  end
end

こんなコードをテストしなきゃいけないとき、ファイルに色々と書き出されてしまうので面倒くさい。 また書き出されたファイルの中身が正しいかチェックするのにもファイルを読まないと行けないので大変。

こんな処理の時はStringIOが便利。 またRSpecでは既存の処理を簡単に置き換えられる。

file = StringIO.new('', 'w')
allow(File).to receive(:open).and_yield(file)

file_write
except(file.string).to eq 'fuga'

FileのOpen時にブロックに渡される引数をStringIOに置き換える。 これでファイルに書き込むはずだった物が簡単に取り出せる。

便利。

ブロックでは無く戻り値を利用してるとき

f = File.open('hoge.txt' , 'w')
f.print 'fuga'
f.close

なときは。。

allow(File).to receive(:open).and_return(file)

こうする。 戻り値を置き換えることもできる。

どうでもいいはなし

Rubyの勉強していたおかげでこのallowとかその辺の処理がどう実現されているのか大体想像が付くようになってきて嬉しい。 進捗と相談しつつテストを書いて完成度を上げていきたい。 

Wordpressの管理ユーザをDB叩いて追加する方法

今日したこと

WordpressのUserをDBから追加する方法

備忘録的に残しておく, 基本的には wp_usersにレコードを追加し wp_usermetaに必要情報を追加する

https://www.web-plains.com/?p=419 こちらを参考にクエリ組み立てさせてもらった。

insert into wp_users (
  user_login,
  user_pass,
  user_registered,
  user_email
) values (
  "namazu",
  md5("nyannyan"),
  "2018-01-25 00:26:19",
  "xxxxxx@mofumofu.com"
);

これでユーザが登録できる user_idはauto_incrementなのでこれで作成したあとに確認.

wp_usermetadataテーブルには

  • wp_dashboard_quick_press_last_post_id
  • dismissed_wp_pointers
  • wp_capabilities
  • wp_user_level
  • nickname

これを設定すればいいらしい

insert into wp_usermeta (
  user_id,
  meta_key,
  meta_value
) values (
  3,
  'wp_dashboard_quick_press_last_post_id',
  5
) , (
  3,
  'dismissed_wp_pointers',
  ''
) , (
  3,
  'wp_capabilities',
  'a:1:{s:13:"administrator";b:1;}'
) , (
  3,
  'wp_user_level',
  '10'
) , (
  3,
  'nickname',
  'namazu'
)

3のところは先程作ったユーザIDに変更。 これで管理者が作れる。

どうでもいいはなし

ちょっと立て込んでて時間がないので今日はこれで。

Nginxの設定がミスっていたらしく,POSTするとなぜかGatewayTimeoutが発生する謎現象に悩まされている。 つらい。

Wordpressのドメインを変更時にCSS等読み込めなくなるやつの対処

きょうしたこと

  • nginxと奮闘
  • バグ潰し
  • 卒論発表原稿用意,発表練習

Wordpressドメイン変更

WordpressドメインをDBに保持してる。 なので初回インストール時の後に、ドメインを変えるとDBのデータが変わらずそのままになってしまい、 CSS等のリンクがすべて古いものになってしまう。

これの対処

以前何回かやったことがあるが,今日は忘れていて,ググったら変なサイトばかり引っかかって辛かったのでやり方をメモしておく.

サイト URL の変更 - WordPress Codex 日本語版

基本的にはこれに従えば良い。

DBの変更で対応する場合は以下を行う

変更SQL

対象となる場所は wp_optionsテーブルのoption_namesiteurl及びhomeのレコードになる

もちろん記事の中で直リンしていたりすると色々なところで変換が必要(よくある全部置換)ではあるのだが、基本的にはここを変えるだけでCSSとかはなんとかなる。

以下クエリで対象は抽出できる

select * from wp_options where option_value = '設定したドメイン( ex https://wordpress.hoge.com)'
mysql> select * from wp_options where option_value = 'https://wp.bs-lab.ks.serviice.cloud.teu.ac.jp'; 
+-----------+-------------+----------------------------------------------+----------+
| option_id | option_name | option_value                                 | autoload |
+-----------+-------------+----------------------------------------------+----------+
|         1 | siteurl     | https://wp.bs-lab.ks.service.cloud.teu.ac.jp | yes      |
|         2 | home        | https://wp.bs-lab.ks.service.cloud.teu.ac.jp | yes      |
+-----------+-------------+----------------------------------------------+----------+
2 rows in set (0.00 sec)

こんな感じで出てくるのでこれをUpdateすればいい

update wp_options  set option_value = '新しいドメイン( ex https://mofumofu.com )'  where option_name = 'siteurl' OR option_name = 'home';

これで使えるようになる.

Nginxで$argsや$request_uriの情報をサブリクエストに渡したい

今日したこと

  • nginxと眠い頭で格闘. 結局負けました. 今日はその話を書きます
  • rubyとか色々書いた
  • 卒論発表スライドアウトラインバトル

Nginxでサブリクエス

http_auth_requestモジュールを用いると,サブリクエストを行ってその結果でアクセス制御が実現できる.

{
   server_name: hoge.com;
   listen 443;

   location / {
        auth_request /auth;
        error_page 401 = @login_page;
        proxy_pass http://app.hoge.com;
   }
   location /auth {
        proxy_pass http://login.hoge.com/auth;
   }

   location @login_page {
        return 302 https://login.hoge.com/login;
   }
}

こんな具合に. 便利なもん.

ここで、http://hoge.com/?type=hogeのようなアクセスを考える, また認証エンドポイントであるlogin.hoge.comtypeを内部で利用し401or200を決定する. この場合サブリクエストにtypeの値をなんとかして付与しなければならない.

以下試したこと

proxy_passに$argsを含める

proxy_pass http://login.hoge.com/auth$is_arg$args; こう設定する. $argsはリクエストのクエリパラメータが入るnginxの変数,なのでこれで渡るのではないだろうか?

=> 無理 $argsは空となり, http://login.hoge.com/auth に単なるGetが送られる.

$argsを一度適当な変数に代入しておきそれをHTTPヘッダに付与させ送ろう

set $original_arg $args;
location /auth {
   proxy_set_header X-Originl-Args $original_arg;
   proxy_pass http://login.hoge.com/auth;
}

これでlogin側ではHTTPヘッダから$argを取り出せるのではないか??

=> 無理 $original_argは空となり,HTTPヘッダ付与は行われない.

惨敗

そもそもサブリクエスト時にコンテキストが切り替わり、$argとか$request_uriとかはすべてサブリクエスト時の値に切り替わっているっぽいことがわかった. なのでいつもの変数ではもともとの値を引くことができない?. そこそこ調べてもこうしてやった例を見つけることが出来なかった. Lua拡張を用いればおそらく引くことができるとは思うがデフォルトのNginxは変えたくない.

結局,色々とごにょって今回の問題には対処した時間もなかったし...

しかし以下のような解決策っぽいのを発見, 思いついた.

そもそも$request_uriなら取れるよ!

調べているうちに,argsは無理だが,request_uriなら引きずり出す方法を発見した.

stackoverflow.com

つまり. locationを正規表現でマッチさせ,そこでキャプチャを行う. キャプチャしたものを変数にsetする. あとは良しなにやる なるほど思いつかなかった....

proxyを2段階にすればいいじゃない

ブラウザ => nginx(1段) => nginx(2段) => (login , app) という構成にすることでも対応できることに気づいた.

nginxの1段目では$argを適当なHTTPヘッダにセットする,そして上で2段目へproxyする. 2段目はいつもどおりauth_requestを行った後APPへProxyする.

サブリクエスト時にHTTPヘッダは引き継がれるので,loginには(特に落とさなければ)HTTPヘッダとして1段目でセットしたHTTPヘッダが飛んでいくし, サブリクエスト時に参照できなくなる変数は$argとか$request_uriとかだけなので,2段目のnginxのコンフィグではサブリクエストの時の設定で1段目でセットしたヘッダを参照することができる.

どうでもいいはなし

運用中のサービスのDBの根本的変更をやるためにDBのデータとか,各所の設定値とかをすべて変更するスクリプトとか書いててめんどいなーっておもった. もっとちゃんとしっかり考えて作れよーという反省.

ボスがなんか、なまずくんに上げるよー!!っていってくれた.

これは君がほしそうだから!!! って... まぁ机の上や某所の壁にけもみみタペストリーとかグッズ大量においてればそうなるか... ふたりともかわいい>_<!