さくらのVPS ファイアーウォールを設定してみる

SSHの設定が済んだら次はファイアーウォールですよね。不要なサービスを止める作業も必要ですがそれだけでは新しくインストールした未設定のサービスが標的にされることもあるのでとりあえずアクセスを弾く機能は必要だと思います。

前回のSSHでも同じですが、この辺の設定を誤るとリモートログイン自体が出来なくなる可能性がありますので設定内容と手順には十分気をつけましょう。さくらのVPSの場合はブラウザ上でシリアル接続できるので最悪そこから設定を戻す事になります。(実は手順ミスって接続切られたorz)
参考:
にわかSEの独り言 CentOS 5.2 x64でiptablesを設定
基本参考サイトの通りなのですが若干気をつける点がありましたのでこちらで試した手順は以下の通り。
今までは/etc/sysconfig/iptablesを編集していたのですが、さくらのVPSにはそのファイルが初期状態でありません。それでコマンドラインで設定することにしました。念のためiptablesがストップしている事を確認し自動起動も外しておいたほうが良いと思います。それは万が一設定を間違って接続できなくなっても再起動すれば良いので、接続手段が無くなってしまったときにリモートか若しくはデーターセンター側のサポートで再起動してもらえば良いからです。
設定の初期化
# iptables -F
受信を全て破棄
# iptables -P INPUT DROP
送信を全て許可
# iptables -P OUTPUT ACCEPT
通過は全て破棄
# iptables -P FORWARD DROP
# サーバから外部に接続したコネクションのレスポンスを許可(2010/10/08追加)
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
PINGの許可
# iptables -A INPUT -p icmp -j ACCEPT
ローカルの許可
# iptables -A INPUT -i lo -j ACCEPT
ブロードキャストアドレス、マルチキャストアドレス宛のパケットを破棄
# iptables -A INPUT -d 255.255.255.255 -j DROP
# iptables -A INPUT -d 224.0.0.1 -j DROP
SSHの許可
# iptables -A INPUT -p tcp –dport 22 -j ACCEPT
SMTPの許可(submissionも追加) 2010/10/08修正
# iptables -A INPUT -p tcp –dport 25 -j ACCEPT
# iptables -A INPUT -p tcp –dport 587 -j ACCEPT
# iptables -A INPUT -p tcp –sport 25 -j ACCEPT
# iptables -A INPUT -p tcp –sport 587 -j ACCEPT
DNSの許可(source port 53 のルールも追加して下さい) 2010/10/08修正
# iptables -A INPUT -p udp –dport 53 -j ACCEPT
# iptables -A INPUT -p udp –sport 53 -j ACCEPT
HTTPの許可
# iptables -A INPUT -p tcp –dport 80 -j ACCEPT
POP3の許可
# iptables -A INPUT -p tcp –dport 110 -j ACCEPT
NTPの許可
# iptables -A INPUT -p udp –dport 123 -j ACCEPT
SNMPの許可
# iptables -A INPUT -p tcp –dport 161 -j ACCEPT
# iptables -A INPUT -p udp –dport 161 -j ACCEPT
SSLの許可
# iptables -A INPUT -p tcp –dport 443 -j ACCEPT
DROP対象をロギング
# iptables -A INPUT -m limit –limit 1/s -j LOG –log-prefix “[IPTABLES INPUT] : “
# iptables -A INPUT -j DROP
# iptables -A FORWARD -m limit –limit 1/s -j LOG –log-prefix “[IPTABLES FORWARD] : “
# iptables -A FORWARD -j DROP
設定の保存
# service iptables save
iptables起動
# service iptables start
ざっとこんな感じですが、FreeBSDのファイアーウォールと違ってハマったところは、私の調査不足なだけかも知れませんがレスポンスについてのルールを設定していないこと。サーバーから外部へのアクセスについては全許可してますが、そのアクセスのレスポンスについては何も設定していないので応答がDROPされてしまいました。今回の場合DNSの応答がDROPされた為、iptablesを起動してからSSH接続の応答が非常に遅くなって焦りました。
ちなみにSSH接続の応答が遅い時は経験上、接続元のIPを逆引きしようとして失敗している場合が多いので/etc/resolv.confで指定しているDNSサーバはアクセス可能なのか、今回のように53番が塞がっていないか確認します。そもそもSSH接続でDNS使うなよって思っているのですが、どうも逆引き→正引きを行ってIPアドレスが正しいものか認証しているようですね。理由が分かるとUseDNSをnoに変えるのもマズイかなっと思った。
追記:2010/10/08
探したらありました。絶対あるはずだと思ってた。
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
最初のACCEPT行の上に書いておけば良いかな。これでsource port 53のルールは不要になりました。多分SMTP関係のsource portのルールも不要になっているはずなので外してメールサーバを構築した時に確認してみます。
参考:
Kozupon.com – 解りにくいiptablesのアルゴリズム!

さくらのVPSを借りて最初にSSH設定

サーバーコストの節約という事で専用サーバ+共用レンタルの構成をVPS2台にしようとお試しで1台借りてみました。

さくらのVPS|VPS(仮想専用サーバ)はさくらインターネット
早速ですが最初はrootユーザしか無いためセキュリティ関連の設定を行います。ちょっと変則的かも知れないかもしれませんが一例として。
まずはroot権限に昇格できる作業ユーザを作成します。俺ルールとしてはこのユーザでメールやウェブは使わないようにしています。ここでは名称をworkuserとして書きますが、実際に作業ユーザを作成する場合は辞書にヒットするような名称は避けましょう。
作業ユーザの作成
# useradd workuser
パスワードの設定
# passwd workuser
ユーザグループの変更(wheelグループに所属させる)
# usermod -g wheel workuser
# usermod -G wheel,workuser workuser
SSHのログイン方法ですがVPSなら運用上SSHログインするユーザは狭い範囲で限定されることが多いと思いますのでクライアント認証の方式にします。
ユーザ用のキーペアを作成しておく
※今回はteratermの機能で作成
メニュー[設定]-[SSHキー作成]
作成した公開鍵をログインするユーザの~/.ssh/authorized_keysに保存
workuserに切り替え
# su – workuser
.sshディレクトリの作成とパーミッションの設定
$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
authorized_keysを新規編集
$ vi ~/.ssh/authorized_keys
クライアントからSCP等で公開鍵をアップロードしても良いのですが、ターミナル上でコピペでも行けるので最初のユーザの場合等はそうしています。あと面倒だからってサーバーでキーペアを作成して秘密鍵をダウンロードするというのはセキュリティ運用上悪いので避けてください。
authorized_keysもパーミッションを適正値に修正します。グループやその他に権限があるとログインできなくなりますので後で慌てる事のないよう必ずチェックしてください。
$ chmod 600 ~/.ssh/authorized_keys
workuserから脱出
$ logout
ここでrootユーザに戻っているはず
次にsshdのログイン方法の設定変更をします。
まずは/etc/ssh/sshd_configの編集
# vi /etc/ssh/sshd_config
以下3行をnoに変更
PermitRootLogin no
PasswordAuthentication no
UsePAM no
1行目はrootでのSSHログインを無効、2行目はパスワード認証を無効、3行目はPAMを無効(多分パスワード認証で使っているものだから不要ということで無効なのかな?)
設定修正が終わったらsshdを再起動します。serviceコマンドでもOK。
# /etc/init.d/sshd restart
次にsuコマンドでrootに成れるユーザの制限をします。
suコマンドの制限
/etc/pam.d/suの下記のコメントを外す
auth sufficient pam_wheel.so trust use_uid
auth required pam_wheel.so use_uid
サーバー再起動
shutdown -r now
作業ユーザでクライアント認証ログインし、さらに
su – でrootに成れるところまで確認する。
一応作業ユーザ以外にもユーザを作ってみてwheelグループに属していない場合はsuコマンドでのユーザ切り替えができないことを確認する。
さくらのVPSの場合は管理画面にシリアル接続のターミナルがあるのでログインできなくなったらそこから設定の見直しをする。
鍵の管理は厳重に取り扱う
root自体のパスワードを無効化した時やroot権限を使う場合でもrootのパスワードを利用したくない場合はsudoの利用設定をします。sudoもwheelグループだけ使えるように制限します。
visudo コマンドでsudoの許可制限
# visudo
以下1行のコメントを外します
%wheel  ALL=(ALL)       ALL
続きは次回に
参考:
yukotan hour: CentOSで特定のユーザがsuでrootに昇格できるよう設定する
myfinder’s blog: さくらのVPSを借りたら真っ先にやるべきssh設定

 

バージョン違いMySQLの同居

同じバージョンのMySQLを2台同じサーバーに入れたりというのは開発環境でやったことがあるのですが、双方とも自動起動してバージョン違いかつ文字コード違いという環境は初めて入れた。結論としては自動起動スクリプトがまるで複数導入を想定していないというのが分かったくらいかな。

やってみた構成はこんな感じ。
  • rpm版同士での複数インストール
    これは普通に競合するのでNG
  • 既存のMySQLクライアントとPHP-MySQLコネクタを残して、MySQL公式サイトのrpm最新版(Serverのみ)をインストール
    これも競合。MySQL公式サイトのものはServerとClientで2つに分けているが、RedHat公式のMySQLはServerとClientとその両方で使う無印パッケージの3つ分かれ、無印とMySQL公式のパッケージで競合を起こす。
  • 既存はrpm版で別途ソース版を入れる
    これは問題なし、自動起動スクリプトは改造が必要
  • 既存がソース版で別途インストールもソース版
    問題は無いがソース版同士なので全ての設定を別に分ける必要が出てくる。自動起動スクリプトは改造が必要。
自動起動スクリプトの改造が必要なのは、configureの設定内容を無視しているのでそのまま使えばデフォルトの構造でmy.cnfやpidファイル、sockファイルを探しに行くという恐ろしいワナがある。結局自動起動スクリプト上のmysql_safeコマンドの行に–defaults-file=[my.cnfのパス]で設定が必要。ちなみにこのオプションは最初に記述しないとエラーになります。他にはDBの初期化(mysql_install_db)をするときに既存のDBを破壊しないように念のためバックアップを取った上でオプションでdatadirやdefaults-fileを設定し回避すること。これは理由がわからないのですがスレーブ用に構築する予定のDBで初期化するときに最初からmy.cnfよりbin-logを抜いていたらエラーになった。これは初期化にはバイナリログが必要だったのか、中途半端なコメントがまずかったのかは不明。別に初期化の時にバイナリログが出されてもたいしたこと無いので別に良いのですけどね。
参考
またレプリケーションも本格的に負荷分散しようとしたら参照系で不要なDBやテーブルを持ってきたくないという事がありました。こちらの設定はスレーブ側のmy.cnfの[mysqld]内に
replicate-do-table=dbname.table
replicate-do-db=dbname
といった感じで追記するだけ。
また文字コードの設定で[mysqld]内に
default-character-set = utf8
だけでなく
skip-character-set-client-handshake
を設定するとPHPから接続したときにいちいち「SET NAMES」を設定しなくても良くなるし、他のセクションにdefault-character-setを入れなくても文字コードが統一される(status;やshow variablesで確認)。
[MySQL] 特定データベース、特定テーブルを指定したレプリケーション設定 | 半袖野郎 blog.hansode.org
あと大きなバッチを使うときに気になるのがメモリ使用量なのですが、折角1行ずつ取り出すのに一斉に配列に入れようとするのはセンス無さ過ぎで見つけ次第指導するレベルなのですが、また全件必要でないのにどうせ詮索スピード変わらないからという理由でLIMITを使わないのもメモリの事を考えてない証拠なのでこれもダメ、でもまさかmysql_query関数の結果が一旦全部メモリにキャッシュされるとは思わなかった。PHP上ではどう見てもメモリが溜まるような処理を書いてないのにメモリ不足になるのはこれのせいだった。そのときはmysql_unbuffered_queryを使いましょう。mysql_unbuffered_queryの制約としてはmysql_data_seekが使えないことや全ての行をフェッチする必要があるという事なので件数の絞込みはしっかりLIMITで設定しましょう。スピードは多分遅くなると思いますがバッチ等では消費メモリの上限を抑えられない方が問題なので。
PHP:SQLクエリのメモリ消費量を抑える:mysql_unbuffered_query