Love澤's Room

技術系ネタをまとめていたブログ。現在はカテゴリにこだわらず更新中。

iptableの設定もsshd_configの設定も正しいのにSSH接続できない時の原因

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


/home/user/のパーミッションが777になっていた。711に戻したらうまく接続できた

FileZillaでファイルを転送しようと思って、一時的にパーミッションを777に設定したところ、転送できなかった。
そこでTeraTermでiptableの確認をしようと思って接続を試みたところ、接続エラーとなった。

もしやと思ってパーミッション設定を711に戻したらうまく接続できた。

その後ググったところ、以下の様なサイトを発見。

SSHが鍵認証されないとき、パーミッションを疑え。 - それマグで!

もちろん、.sshから上位フォルダのパーミッションも必要
chmod 755 /home/takuya
これがうっかり777になってた。ホームディレクトリが777だと永遠にauthorized_keysは無効化される。

SSHで公開鍵認証を使う - Pistolfly

クライアント側のユーザのホームディレクトリのパーミッションにも注意する。所有者以外の書込み権を設定してあるとだめ。
たとえば、/home/hogeのパーミッションが777の場合、公開鍵認証でsshログインしようとすると、
Permission denied (publickey,gssapi-with-mic).
というエラーになる。この場合、サーバ側のログ(/var/log/secure)では
Authentication refused: bad ownership or modes for directory /home/hoge
となっていて、/hoem/hogeのパーミッションに問題があるということ。
所有者以外の書込み権を設定してあるとだめ。700、711、755にすればOK。

なるほど。

CentOSで文字コードの確認&変更をする方法(nkfコマンド)

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


nkfコマンドを利用する。他の方法を見つけた時はまたその都度記事にしていきます。

インストール

# yum -y install nkf

文字コードの確認

# nkf -g *

"*"だとディレクトリ内の全てのファイルの文字コードを確認する。ファイルを指定する場合はその都度ファイル名を記述する。
実行結果は以下。

[root@myserv]# nkf -g *
hoge.class:BINARY
hoge.java:ASCII (LF)
foo.txt:UTF-8 (LF)
bar.txt:Shift_JIS (LF)
...(以下略)

文字コードの変更(UTF-8へ変更する場合)

# nkf -w foo.txt > bar.txt

オプションで変更後の文字コードを指定する。

詳細はヘルプ参照。主要な文字コードとオプションの対応は以下の通り。

  • -j または --jis : JIS 7bit
  • -s または --sjis : Shift JIS
  • -e または --euc : EUC-JP
  • -w または --utf8 : UTF-8

さらにオプションで上書き保存なども可能

  • --in-place : 上書き保存
  • --overwrite : 上書き保存(元のファイルのタイムスタンプを保持)

Cron <root@hogehoge> /root/tripwire.sh というメールが届いた時にしたこと(メモ)

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


管理者宛に、以下の様なメールが届いた。

### Error: File could not be opened.
### Filename: /usr/local/tripwire/lib/tripwire/hogehoge.twd
### No such file or directory
### Exiting...
Null message body; hope that's ok
### Error: Incorrect site passphrase.
### Exiting...
### Error: Incorrect local passphrase.
### Exiting...
続きを読む

PHPでSESSIONの有効期限を設定する方法

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


練習としてあるwebサービスを実装中なのだが、SESSIONを利用して、ログインしている人の情報(ログイン名とか)を保持するようなしくみを組み込んだ。
その際、SESSIONの有効期限などは特に意識していなかったが、どこかのサイトで「何も設定していない場合は24分で期限がきれますよ」的なことが書いてあった。

が、しかし、なぜか一晩放置してもSESSIONの有効期限が切れないという状況になっていたので、今回はSESSIONの有効期限を設定した。
参考サイトによると、php.iniファイルに記述する方法と.htaccessファイルに記述する方法があるらしい。

php.iniファイルをfindで検索してみたが見つからなかったので、Webサービスのトップノードにある.htaccessファイルに以下を記述することで対応した。

php_value session.gc_maxlifetime 900
php_value session.gc_probability 1
php_value session.gc_divisor 10

gc_maxlifetimeがSESSIONの有効期限を設定する変数だそう。秒で指定する。
今回は15分=900秒を設定した。普通は30分とかを設定するっぽいが、今回はとくに深い理由があるわけではない。

gc_probabilityとgc_divisorは、SESSIONを管理しているファイルを削除する頻度を設定するもの。というのも、誰かがSESSIONを発行するたびに、サーバー内部で、SESSIONファイルなるものがその都度作成されるらしい。ほっといたらサーバーの容量を圧迫するので、それを避けるために、SESSIONが発行されたら古いSESSIONファイルを削除する機能(ガーベージコレクタ)を呼び出してお掃除しているそうだ。とはいえ、毎回ガーベージコレクタを起動していても無駄じゃね?ということで、適当なタイミングでお掃除しよう、ということらしい。
今回は、gc_probability / gc_divisor = 1/10 つまり、10回に1回くらいはお掃除する設定にした。普通は1/100とか1/1000くらいにしておくらしい。

(参考サイト)

MariaDB(MySQL)でカラムコメントを追加・確認する方法

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


テーブル追加時に以下のようにコメントを書くことができる。

MariaDB [test_db]> create table test_table (
    -> id int not null primary key auto_increment,
    -> name varchar(20) not null,
    -> birthday date comment '誕生日'
    -> );
Query OK, 0 rows affected (0.20 sec)

このとき、comment文で書いたコメントを確認する場合、以下の方法で確認することが出来る。

MariaDB [test_db]> show full columns from test_table;
+----------+-------------+-----------------+------+-----+---------+----------------+---------------------------------+-----------+
| Field    | Type        | Collation       | Null | Key | Default | Extra          | Privileges                      | Comment   |
+----------+-------------+-----------------+------+-----+---------+----------------+---------------------------------+-----------+
| id       | int(11)     | NULL            | NO   | PRI | NULL    | auto_increment | select,insert,update,references |           |
| name     | varchar(20) | utf8_general_ci | NO   |     | NULL    |                | select,insert,update,references |           |
| birthday | date        | NULL            | YES  |     | NULL    |                | select,insert,update,references | 誕生日    |
+----------+-------------+-----------------+------+-----+---------+----------------+---------------------------------+-----------+
3 rows in set (0.00 sec)

Webサービスで、ある素材を利用しつつ、素材へのアクセス制限をかける方法(htaccessを利用)

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


htaccessを用いることで、ファイルにアクセス制限をかけることが出来ます。

今回目標とするのは
「あるサービス内で色々な素材を使うが、その素材自体にはアクセス出来ないようにする」
です。ベーシック認証などの話ではないのでご注意下さい。うだうだ書いていますので結局どうしたら良いのかさっさと知りたい、という方は、記事の最後の方に飛んで下さい。

素材自体にアクセス出来ないようにする方法

素材とそのディレクトリにアクセス制限をかける方法として

  1. そもそも、素材置き場をpublic_html以下ではないどこか別のディレクトリに置く
  2. .htaccessを利用してアクセス制限をかける

といったことが考えられました。

もちろん前者が確実なのでしょうが、もろもろの都合により、どうしてもpublic_html以下に素材を置かなければいけないこともあるかと思います。そういった場合もあるかと思ったので、今回は前者「.htaccessを利用してアクセス制限をかける」ということを試みました。

なお、今回はファイル構成が以下のようになっているとして話を進めます。

  • public_html
    • material_search.php
    • materialディレクトリ
      • creator1ディレクトリ
        • image1.png
        • image2.gif
      • creator2ディレクトリ
        • image3.pdf
        • image4.jpg

materialディレクトリ以下へのアクセスを全て拒否する場合

単に、素材置場(materialディレクトリ)以下の全てのファイル・ディレクトリへのアクセスを拒否したい場合は非常に簡単です。materialディレクトリに.htaccessファイルを作成し、以下のように記述します。

deny from all

しかしこの場合、サービス内で素材を利用したい場合にも利用できなくなります。つまり、material_search.phpでの検索結果、素材を表示する際にも、アクセスできなくなってしまう、ということです。(自分の設定の問題かもしれませんが。)

今回の目標としては、サービス内では素材を利用できるようにしたいので、このままではだめです。

サービス内で素材を利用しつつ、素材へのアクセス制限をかける

そこで、.htaccessファイルを以下のように書き換えます。

SetEnvIf Referer "^http://hogehoge.com" ShowOK
order deny,allow
deny from all
allow from env=ShowOK

1行目の意味ですが、参考サイトによると

「SetEnvIf」とは、「ある条件が成立した場合に環境変数を設定する」という意味です。
上記の場合は、

  • Referer(参照元)に
  • http://hogehoge.com」という文字列が含まれていた場合に
  • 環境変数に「ShowOK」を設定する

という意味になります。

ということだそうです(『「~」という文字列が』の部分のURLだけ書き換えています)。

以上のようにすることで、例えば、外部サイトからリンクをたどってきたの場合は「http://hogehoge.com」の部分の値が変わるので、ShowOKとならず、また、素材へのURLを直接入力する場合は、Refererの値がないので、ShowOKとなりません。

また、参考サイトで、URLを記述する際の注意点が挙げられています。

  • URLを記述する際には、「 . 」(ドット)は「 \. 」のように円記号(=バックスラッシュ)を前に加えて下さい。 これは、正規表現という記述方法を使っているための仕様です。(※半角文字で記述)
  • また、URLは必ず「http://」から書き、先頭には半角で「 ^ 」(ハット)記号を加えて下さい。 これらを省略しても動作はしますが、省略すると、リンク元ページに少し工夫をするだけでアクセス制限を突破されてしまいます。
  • URLの先頭に「www」がある場合、「www」を省略しても同じページにアクセスできる場合があります。 (例えば、http://www.example.com/ でも http://example.com/ でもアクセスできるなど。) その場合は、両方のURLを記述しておきましょう。

※許可したいURLが複数ある場合は、この行を複数回列挙します。

というわけで、長々となりましたが、以上のようにすることで、冒頭に上げた目標を達成することが出来ます。

(参考サイト)
直リンクを防ぐには?…禁止と言っても無駄 [ホームページ作成] All About

MariaDB 10.0.12でDynamic Columns(動的カラム)を試してみた

新サイトへ移転しました
約3秒後に自動的にリダイレクトします。


MariaDBではDynamic Columnsなるものが実装されている。version 5.3から新たに導入されたもののようだ。

Dynamic Columns - MariaDB Knowledge Baseより

MariaDB starting with 5.3
Dynamic columns first appeared in MariaDB-5.3

「MariaDB Dynamic Columns」でぐぐってみたけど、日本語のページがほとんどHITしなかったのでちょっとかいてみる。(実は既にあったりして。。)>>(追記:もうちょっとぐぐったら、すぐ見つかった。結構たくさん。お恥ずかしい。。

今回の記事は、実際にMariaDBでDynamic Columnsを使ってみた過程をそのまま載せています。後日またまとめる予定ですが、長いのであしからず。
最後の方に、動的カラムからJSON形式でデータを得る方法(といっても超簡単)を載せています。そちらが目当ての方は最下部へどうぞ。

◯テーブル作成

「blob」と指定することで、カラムの追加・削除などが動的に行えるようになる。

MariaDB [test_db]> create table assets(
    -> item_name varchar(32) primary key,
    -> dynamic_cols blob
    -> );
Query OK, 0 rows affected (0.20 sec)

ちなみに、blobってどういう意味だろうと思ってALCさんに尋ねたら「輪郭がぼやけているもの、おぼろげなもの、フニャフニャした物体[生き物]」「〈俗〉でぶ、丸ぽちゃ、ふとっちょ」といった意味があるようだ(ALCで調べました)。

さっそくフィールドの制約などを確認してみる。

MariaDB [test_db]> show fields from assets;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| item_name    | varchar(32) | NO   | PRI | NULL    |       |
| dynamic_cols | blob        | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

おー、Typeがblobになってる(そりゃそうだ。)

◯テーブルに追加

動的カラムにデータをつかするには以下のようにする。以下の例は、2つの動的カラム(color=blue, size=XL)をもつデータを追加するときの例。

MariaDB [test_db]> insert into assets values
    -> ('MariaDB Tshirt', column_create('color', 'blue', 'size', 'XL')
    -> );
Query OK, 1 row affected (0.04 sec)

この段階でテーブルの中身を確認してみる。

+----------------+--------------------------------+
| item_name      | dynamic_cols                   |
+----------------+--------------------------------+
| MariaDB Tshirt |           3 sizecolor!XL!blue |
+----------------+--------------------------------+
1 row in set (0.00 sec)

なんか、よくわからん。が、2でもなく4でもなく、「3」という数字が。どういうことだ。まぁ今は置いておく。
で、上と同様にして、今度はcolor=black, price=500という動的カラムをもつデータを追加する(この表現は正しいのか?)。

MariaDB [test_db]> insert into assets values
    -> ('Thinkpad Laptop', column_create('color', 'black', 'price', 500));
Query OK, 1 row affected (0.03 sec)

書き方が変わってるのはご愛嬌。同様に中身を確認してみる。

MariaDB [test_db]> select * from assets;
+-----------------+---------------------------------+
| item_name       | dynamic_cols                    |
+-----------------+---------------------------------+
| MariaDB Tshirt  |          3 sizecolor!XL!blue  |
| Thinkpad Laptop |
     ` colorprice!black・ |
+-----------------+---------------------------------+
2 rows in set (0.00 sec)

表示が崩れていますが、これは、このブログで表示が崩れているのではなく、本当にこのように崩れて表示されました。なぜだ。今回は「3 pricesize!500!black」と表示されると予想してたのに。

公式ページの説明を読み進めていくと、以下のようにすると決行いい感じの情報が得られることがわかった。

MariaDB [test_db]> select item_name, column_list(dynamic_cols) from assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB Tshirt  | `size`,`color`            |
| Thinkpad Laptop | `color`,`price`           |
+-----------------+---------------------------+
2 rows in set (0.00 sec)

◯動的カラムからデータを取り出す

上のままでは、動的カラムからいい感じの情報を取り出せない。ちゃんと取り出すには以下のようにする。

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'color' as char) from assets;
+-----------------+-------------------------------------------+
| item_name       | column_get(dynamic_cols, 'color' as char) |
+-----------------+-------------------------------------------+
| MariaDB Tshirt  | blue                                      |
| Thinkpad Laptop | black                                     |
+-----------------+-------------------------------------------+
2 rows in set (0.00 sec)

同様にして、色々と試してみる。

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'size' as char) from assets;
+-----------------+------------------------------------------+
| item_name       | column_get(dynamic_cols, 'size' as char) |
+-----------------+------------------------------------------+
| MariaDB Tshirt  | XL                                       |
| Thinkpad Laptop | NULL                                     |
+-----------------+------------------------------------------+
2 rows in set (0.00 sec)

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'price' as char) from assets;
+-----------------+-------------------------------------------+
| item_name       | column_get(dynamic_cols, 'price' as char) |
+-----------------+-------------------------------------------+
| MariaDB Tshirt  | NULL                                      |
| Thinkpad Laptop | 500                                       |
+-----------------+-------------------------------------------+
2 rows in set (0.00 sec)

Thinkpad Laptopのsizeだったり、MariaDB Tshirtのpriceのように、設定されていないものはNULLとなるらしい。どうせなら、設定されていないものは表示されないで欲しかったかな。以下の実行結果から想像したことだが、「'color' as char」や「'size' as char」の部分は、データを取り出すときにchar型やint型に変換してくれてるっぽい。

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'price' as int) from assets;
+-----------------+------------------------------------------+
| item_name       | column_get(dynamic_cols, 'price' as int) |
+-----------------+------------------------------------------+
| MariaDB Tshirt  |                                     NULL |
| Thinkpad Laptop |                                      500 |
+-----------------+------------------------------------------+
2 rows in set (0.00 sec)

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'price' as char) from assets;
+-----------------+-------------------------------------------+
| item_name       | column_get(dynamic_cols, 'price' as char) |
+-----------------+-------------------------------------------+
| MariaDB Tshirt  | NULL                                      |
| Thinkpad Laptop | 500                                       |
+-----------------+-------------------------------------------+
2 rows in set (0.00 sec)

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'price' as double) from assets;
+-----------------+---------------------------------------------+
| item_name       | column_get(dynamic_cols, 'price' as double) |
+-----------------+---------------------------------------------+
| MariaDB Tshirt  |                                        NULL |
| Thinkpad Laptop |                                         500 |
+-----------------+---------------------------------------------+
2 rows in set (0.00 sec)

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'size' as double) from assets;
+-----------------+--------------------------------------------+
| item_name       | column_get(dynamic_cols, 'size' as double) |
+-----------------+--------------------------------------------+
| MariaDB Tshirt  |                                          0 |
| Thinkpad Laptop |                                       NULL |
+-----------------+--------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'size' as int) from assets;
+-----------------+-----------------------------------------+
| item_name       | column_get(dynamic_cols, 'size' as int) |
+-----------------+-----------------------------------------+
| MariaDB Tshirt  |                                       0 |
| Thinkpad Laptop |                                    NULL |
+-----------------+-----------------------------------------+
2 rows in set, 1 warning (0.00 sec)

なるほど、文字で格納されているものを数字に変換しようとなると0、ただし、値が入っていないものはNULLと。まぁ当然といえば当然か。

ちなみに、型変換を行う部分を省略するとエラーとなった。かならず、型を指定して取り出さないといけない様子。

MariaDB [test_db]> select item_name, column_get(dynamic_cols, 'color') from assets;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') from assets' at line 1

◯カラムの追加・削除

動的カラムは追加・削除が可能らしい。"color"=blackであるデータの"price"情報を削除する場合は以下のようにする。

MariaDB [test_db]> update assets set dynamic_cols=column_delete(dynamic_cols, "price") where column_get(dynamic_col
s, 'color' as char)='black';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test_db]> select item_name, column_list(dynamic_cols) from assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB Tshirt  | `size`,`color`            |
| Thinkpad Laptop | `color`                   |
+-----------------+---------------------------+
2 rows in set (0.00 sec)

どのようになったか確認もしてみたが、Thinkpad Laptopから'price'の情報がなくなっている。

逆に、新たにカラムを追加する場合は以下のようにする。

MariaDB [test_db]> update assets set dynamic_cols=column_add(dynamic_cols, "warranty", "3 years") where item_name='
Thinkpad Laptop';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test_db]> select item_name, column_list(dynamic_cols) from assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB Tshirt  | `size`,`color`            |
| Thinkpad Laptop | `color`,`warranty`        |
+-----------------+---------------------------+
2 rows in set (0.00 sec)

◯動的カラムの中身をJSONで取り出す。

Mariadb 10.0.1からは、動的カラムの中身をJSONで取り出す、ということも可能なようだ。なんてことだ。便利すぎる。

MariaDB [test_db]> select item_name, column_json(dynamic_cols) from assets;
+-----------------+----------------------------------------+
| item_name       | column_json(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB Tshirt  | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+
2 rows in set (0.00 sec)


公式サイトにもっと詳しい情報(英語)が載ってます。
(公式サイト)
Dynamic Columns - MariaDB Knowledge Base
Dynamic Columns from MariaDB 10 - MariaDB Knowledge Base