2010年6月30日水曜日

SUZ-LAB謹製 CentOS AMI アップデート (5.5.1)

スズキです。

とりあえず、"us-west-1"に、32bit、EBS版のみでリリースです。

Manifestは下記となります。
811118151095/suz-lab_ebs_centos-core-i386-5.5.1
("suz"で検索したら、見つかると思います)

アップデート内容は下記です。

(1) "yum update"でパッケージを"CentOS 5.5"相応に

(2) SELinuxを"disabled"に

(3) 以下で紹介したMonitの監視をデフォルトに

▼Monitで"crond/syslog/sshd"の監視
http://blog.suz-lab.com/2010/06/monitcrondsyslogsshd.html

▼Monitを"init"経由で起動
http://blog.suz-lab.com/2010/06/monitinit.html

▼Monitでプロセスの再起動
http://blog.suz-lab.com/2010/06/monit.html

Enjoy!

--------
http://www.suz-lab.com

2010年6月29日火曜日

Monitで"crond/syslog/sshd"の監視

スズキです。

"/etc/monit.d/"以下に下記のファイルを配置すれば実現できます。

--------【crond.conf】--------
check process crond with pidfile /var/run/crond.pid
  start program = "/etc/init.d/crond start"
  stop program = "/etc/init.d/crond stop"
  if 5 restarts within 5 cycles then timeout
--------

--------【syslog.conf】--------
check process syslog with pidfile /var/run/syslogd.pid
  start program = "/etc/init.d/syslog start"
  stop program = "/etc/init.d/syslog stop"
  if 5 restarts within 5 cycles then timeout
--------

--------【sshd.conf】--------
check process sshd with pidfile /var/run/sshd.pid
  start program = "/etc/init.d/sshd start"
  stop program = "/etc/init.d/sshd stop"
  if failed port 22 protocol ssh then restart
  if 5 restarts within 5 cycles then timeout
--------

各サービスの設定例はこちらにいろいろ載っており、
http://mmonit.com/wiki/Monit/ConfigurationExamples
上記の参考にもしています。

"SUZ-LAB AMI"にも、ここまで組み込んでおこう。

--------
http://www.suz-lab.com

Monitを"init"経由で起動

スズキです。

そもそもMonitが停止したときの対策として、"init"経由で起動するようにしてみました。
こうすることで、Monitが異常終了しても、"init"が再び立ち上げてくれます。

まず、Monitの導入ですが、下記で紹介しています。
http://blog.suz-lab.com/2010/06/monit.html

次に、"/etc/monit.conf"を以下のようにします。
--------【monit.conf】--------
set init # init経由の起動
set daemon 60 # 60秒ごとにチェック
set logfile syslog facility log_daemon # ログの出力
include /etc/monit.d/*.conf # 設定ファイルのインクルード
--------

そして、"/etc/inittab"にも下記のように記述します。
--------【inittab】--------
...
# Monit
mo:2345:respawn:/usr/bin/monit -Ic /etc/monit.conf
--------

最後に、次のコマンドでinittabの設定を反映します。
# kill -HUP 1

試しに、"killall -KILL monit"しても、"/var/log/messages"のログより、
Monitが再び立ち上げなおされていることがわかります。

--------【inittab】--------
...
...: /etc/monit.conf:239: Warning: include files not found '/etc/monit.d/*.conf'
...: Starting monit daemon
...: 'localhost' Monit started
--------

次は、cronなどの基本的なサービスを、Monitで監視してみよう。

--------
http://www.suz-lab.com

RDSでSSL接続がサポート(AWS)

スズキです。

"Amazon Web Services Blog"で「RDSでSSL接続がサポート」の記事が公開されました。
http://aws.typepad.com/aws/2010/06/amazon-rds-support-for-ssl-connections.html

早速、RDSを作成して、適当なクライアントから、以下のような手順で検証してみました。

まず、いつもどおりにMySQLに接続して、SSL接続が必須のユーザーを作成します。
mysql> GRANT ALL PRIVILEGES ON suz.* TO suz@"%" IDENTIFIED BY 'suz' REQUIRE SSL;

次の、以下のように公開鍵を取得して、上記で作成したユーザーで、取得した公開鍵を利用して接続します。
shell# curl -OL https://rds.amazonaws.com/doc/mysql-ssl-ca-cert.pem
shell# mysql -u suz -p -h xxx.xxx.us-west-1.rds.amazonaws.com --ssl_ca=mysql-ssl-ca-cert.pem

すると、無事、接続できました。

念のため、公開鍵を指定せず、いつもどおりの接続を試してみると、
shell# mysql -u suz -p -h xxx.xxx.us-west-1.rds.amazonaws.com

こちらは、無事、接続に失敗しました。

こういうネタは、発表後、24時間以内に検証して、ブログの記事にしていきたいなー...

--------
http://www.suz-lab.com

2010年6月28日月曜日

"MySQL Proxy"を"Monit"で監視

スズキです。

こんどは、こちらでインストールしたような"MySQL Proxy"を"Monit"で監視します。
http://blog.suz-lab.com/2010/05/centosmysql-proxy.html

以前紹介したMySQLのように"MySQL Proxy"を監視すると、

----------【/etc/monit.d/mysql-proxy.conf】----------
check process mysql-proxy with pidfile /var/run/mysql-proxy.pid
  start program "/etc/init.d/mysql-proxy start"
  stop program "/etc/init.d/mysql-proxy stop"
  if failed port 4040 protocol mysql then restart
  if 5 restarts within 5 cycles then timeout
----------
http://blog.suz-lab.com/2010/06/monit.html

以下のようになってしまいました...

----------【/var/log/messages】----------
...: Starting monit daemon
...: 'localhost.localdomain' Monit started
...: MYSQL: login failed
...: 'mysql-proxy' failed protocol test [MYSQL] at INET[localhost:4040] via TCP
...: 'mysql-proxy' trying to restart
...: 'mysql-proxy' stop: /etc/init.d/mysql-proxy
...: 'mysql-proxy' start: /etc/init.d/mysql-proxy
...: MYSQL: login failed
...: 'mysql-proxy' failed protocol test [MYSQL] at INET[localhost:4040] via TCP
...: 'mysql-proxy' trying to restart
...: 'mysql-proxy' stop: /etc/init.d/mysql-proxy
...: 'mysql-proxy' start: /etc/init.d/mysql-proxy
...
----------

"protocol mysql"がうまく機能していないようだったので、最終的に下記のように、
その部分をはずしたら、無事、機能するようになりました。

----------【/etc/monit.d/mysql-proxy.conf】----------
check process mysql-proxy with pidfile /var/run/mysql-proxy.pid
  start program "/etc/init.d/mysql-proxy start"
  stop program "/etc/init.d/mysql-proxy stop"
  if failed port 4040 protocol mysql then restart
  if 5 restarts within 5 cycles then timeout
----------

"Monit"は"SUZ-LAB AMI"に組み込みにしよう。(init起動で...)

--------
http://www.suz-lab.com

Monitでプロセスの再起動

スズキです。

下記に伴ってdaemontools相応のCentOSっぽいツールを探してみたら、
http://blog.suz-lab.com/2010/06/mysql-proxy.html
Monitというものを見つけました。
http://mmonit.com/monit/

▼"yum"で簡単にインストールできます
# yum install monit

▼ "/etc/monit.conf"のパーミッションを700にする必要があります。
# /etc/init.d/monit start
Starting monit: monit: The control file '/etc/monit.conf' must have permissions
no more than -rwx------ (0700); right now permissions are -rw-r--r-- (0644).
# chmod 700 /etc/monit.conf

▼ "/etc/monit.conf"で共通の設定を行います。
--------【/etc/monit.conf】--------
set daemon 30
--------
※ 30秒ごとにチェックです。

▼ "/etc/monit.d/*"に監視するサービスを設定します。
--------【/etc/monit.d/mysqld.conf】--------
check process mysql with pidfile /var/run/mysqld/mysqld.pid
  start program "/etc/init.d/mysqld start"
  stop program "/etc/init.d/mysqld stop"
  if failed port 3306 protocol mysql then restart
  if 5 restarts within 5 cycles then timeout
--------
※ MySQLの場合です。

これで、"kill -9"のようにMySQLを不正終了しても、
勝手に立ち上げなおしてくれます。

"mysql-proxy"にも適用しよう。

--------
http://www.suz-lab.com

AWS関係の書籍

スズキです。

まだ、数が少ないので、まとめて見ました。(新しい順です)

▼よくわかるAmazonEC2/S3入門
2010/06 - http://www.amazon.co.jp/dp/4774142840

▼AmazonCloudテクニカルガイド
2010/04 - http://www.amazon.co.jp/dp/4844328549

▼クラウド Amazon EC2/S3のすべて
2009/11 - http://www.amazon.co.jp/dp/4822234371

▼Amazon EC2/S3/EBS クラウドコンピューティングによる仮想サーバ構築
2009/08 - http://www.amazon.co.jp/dp/4883376680

▼Amazon EC2/S3クラウド入門
2008/12 - http://www.amazon.co.jp/dp/4798021555

レビューもしていきたいなー。

--------
http://www.suz-lab.com

2010年6月24日木曜日

UIScrollViewで拡大縮小(iPhone/iPad)

スズキです。

iPhone/iPadをピンチイン/ピンチアウトして、拡大縮小する方法です。

ポイントはUIViewControllerのサブクラスでのUIScrollViewの利用です。

具体的には、"loadView"をオーバーライドして、その中で拡大縮小したい
UIViewとの間にUIScrollViewをかますように処理します。

またUIScrollViewDelegateの"viewForZoomingInScrollView"を
実装する必要もあります。

まあ、コードを見たほうが早いでしょう...

--------【Objective-C】--------
...
@implementation BoardViewController

UIView *view; // 拡大縮小させるView

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle
*)nibBundleOrNil {
  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
    self.title = @"Board";
  }
  return self;
}

- (void)loadView {
  // 作成するViewの幅
  CGFloat width = self.parentViewController.view.frame.size.width;
  // 作成するViewの高さ(タブバーとステータスバーを除く)
  CGFloat height = self.parentViewController.view.frame.size.height
      - self.tabBarController.tabBar.frame.size.height - 20;
  // 拡大縮小するView
  view = [[BoardView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
  // UIScrollView
  UIScrollView *scrollView = [
      [UIScrollView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
  [scrollView addSubview:view]; // 拡大縮小するViewをUIScrollViewに追加
  [scrollView setDelegate:self]; // デリゲートを自分自身に
  [scrollView setContentSize:view.frame.size];
  [scrollView setMinimumZoomScale:1.0];
  [scrollView setMaximumZoomScale:2.0];
  [scrollView setBounces:NO];
  [scrollView setBouncesZoom:NO];
  [self setView:scrollView]; // UIScrollViewを追加
  [scrollView release];
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  return view; // 拡大縮小するViewを返す
}

- (void)dealloc {
  [view release];
  [super dealloc];
}

@end
--------
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/Classes/Tabs/BoardViewController.m?r=13

ソース全体は下記となります。
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/?r=13

次は回転の部分を作りこもう。

--------
http://www.suz-lab.com

MySQLのバイナリログの削除

スズキです。

下記のように、MySQLのコマンドでできます。

> PURGE MASTER LOGS TO 'mysqld-bin.000010';
※mysqld-bin.000010未満のファイルが削除されます

今まで、バイナリログはためっぱなしだったなー。

--------
http://www.suz-lab.com

2010年6月23日水曜日

"MySQL Proxy"が異常終了

スズキです。

下記で紹介されているように、
http://bugs.mysql.com/bug.php?id=51951
"rw-splitting.lua"を利用して、DBの負荷が高く、
大量のSELECT/INSERTを実行したときに、異常終了することがあるようです。
(というか、ありました...)

とりあえず"daemontools"のようなもので、プロセス監視&起動の仕組みをいれる感じでしょうか?
"monit"のほうが、CentOSっぽいか?
http://labs.unoh.net/2008/03/_monit.html

--------
http://www.suz-lab.com

2010年6月22日火曜日

図形の描画(iPhone/iPad)

スズキです。

図形の描画は、UIViewのサブクラスで、以下のように
"(void)drawRect:(CGRect)rect"をオーバーライドして実現します。

--------【BoardView.m】--------
...
- (void)drawRect:(CGRect)rect {
  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
  CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
  CGContextSetLineWidth(context, 5.0);
  CGContextAddRect(context,
      CGRectMake((768 - 11 * 45.0) / 2 , 50.0, 11 * 45.0, 19 * 45.0)
  );
  CGPoint starPoints[] = {
      {(768 - 11 * 45.0) / 2, 50.0 + 19 * 45.0 / 2},
      {(768 - 11 * 45.0) / 2 + 11 * 45.0, 50.0 + 19 * 45.0 / 2}
  };
  CGContextAddLines(context,starPoints,sizeof(starPoints)/sizeof(*starPoints));
  CGContextStrokePath(context);
}
...
--------
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/Classes/Tabs/BoardView.m?r=12

実際には、CGContext系の関数を用いて図形を描画しているのですが、
詳細はこちらになります。
http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html

そして、上記UIViewのサブクラスは、
UIコントローラーのサブクラス上の"(void)loadView"で、下記のように設定しています。

--------【BoardViewController.m】--------
....
- (void)loadView {
  self.view = [[BoardView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
  [self.view release];
}
...
--------
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/Classes/Tabs/BoardViewController.m?r=12

早く、フットサルコート、完成させないと...

--------
http://www.suz-lab.com

2010年6月21日月曜日

Nagiosの"check_dns"でCNAMEがチェックできない

スズキです。

AWSのELBを用いるとき、DNSの設定にCNAMEを用いますが、
そのチェックが、Nagiosの"check_dns"でできませんでした…
(対象のバージョン(プラグイン)は"1.4.14"です)

仕方ないので下記のように、"/etc/nagios/objects/commands.cfg"に"check_dns_noip"を作り、
名前解決したIPアドレスのチェックをしないものを使うようにしました。

--------【commands.cfg】--------
# 'check_dns' command definition
define command {
  command_name check_dns
  command_line $USER1$/check_dns -H $HOSTADDRESS$ -a $ARG1$
}
# 'check_dns_noip' command definition
define command {
  command_name check_dns_noip
  command_line $USER1$/check_dns -H $HOSTADDRESS$
}
--------

そろそろ、Nagiosのプラグインを作っていこう…(AWS関係で...)

--------
http://www.suz-lab.com

"Interface Builder"を使わない開発(iPhone/iPad)

スズキです。

使わない方が、僕にはあってるようです。(全ソースは下記です)
http://code.google.com/p/suz-lab-ios/source/browse/?r=9#svn/trunk/FutsalBoard

(1) "Window-based Application"プロジェクトを作成します。

(2) "MainWindows.xib"を削除します。

(3) "FutsalBoard-Info.plist"から"Main nib file base name"を削除します。
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/FutsalBoard-Info.plist?r=9

(4) "main.m"のUIApplicationMainの第四引数に
該当デリゲート"FutsalBoardAppDelegate"を指定します。
--------【main.m】--------
...
int main(int argc, char *argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  int retVal = UIApplicationMain(argc, argv, nil, @"FutsalBoardAppDelegate");
  [pool release];
  return retVal;
}
--------
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/main.m?r=9

(5) 実際のデリゲートは下記のような感じです。
--------【FutsalBoardAppDelegate.m】--------
#import "FutsalBoardAppDelegate.h"
#import "FutsalBoardTabBarController.h"
#import "BoardViewController.h"

@implementation FutsalBoardAppDelegate

UIWindow *window;
UITabBarController *tabBarController;

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // View
  UIViewController *viewController = [[BoardViewController alloc] init];
  // Tab
  tabBarController = [FutsalBoardTabBarController new];
  [tabBarController setViewControllers:[
    NSArray arrayWithObjects:viewController, nil]];
  tabBarController.view.backgroundColor = [UIColor whiteColor];
  // Release
  [viewController release];
  // Window
  window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  [window addSubview:tabBarController.view];
  [window makeKeyAndVisible];
  return YES;
}

- (void)dealloc {
  [tabBarController release];
  [window release];
  [super dealloc];
}

@end
--------
http://code.google.com/p/suz-lab-ios/source/browse/trunk/FutsalBoard/Classes/FutsalBoardAppDelegate.m?r=9

これで、"Interface Builder"を使わずにアプリを作成する土台ができました。

--------
http://www.suz-lab.com

2010年6月16日水曜日

Openswanの"ipsec verify"対応を起動しながら行う

スズキです。

下記のやり方は、再起動前提のやり方だったので、
http://blog.suz-lab.com/2010/06/openswanipsec.html
今回は、起動しながらの対応です。

ポイントは、こちらの対応になると思います。

NETKEY detected, testing for disabled ICMP send_redirects [FAILED]
  Please disable /proc/sys/net/ipv4/conf/*/send_redirects
  or NETKEY will cause the sending of bogus ICMP redirects!

NETKEY detected, testing for disabled ICMP accept_redirects [FAILED]
  Please disable /proc/sys/net/ipv4/conf/*/accept_redirects
  or NETKEY will accept bogus ICMP redirects!

まず、対象のファイルを確認します。

# ls /proc/sys/net/ipv4/conf/*/send_redirects
/proc/sys/net/ipv4/conf/all/send_redirects
/proc/sys/net/ipv4/conf/default/send_redirects
/proc/sys/net/ipv4/conf/eth0/send_redirects
/proc/sys/net/ipv4/conf/lo/send_redirects
# ls /proc/sys/net/ipv4/conf/*/accept_redirects
/proc/sys/net/ipv4/conf/all/accept_redirects
/proc/sys/net/ipv4/conf/default/accept_redirects
/proc/sys/net/ipv4/conf/eth0/accept_redirects
/proc/sys/net/ipv4/conf/lo/accept_redirects

上記ファイルの中身を0にします。

# echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
# echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
# echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects
# echo 0 > /proc/sys/net/ipv4/conf/lo/send_redirects
# echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
# echo 0 > /proc/sys/net/ipv4/conf/default/accept_redirects
# echo 0 > /proc/sys/net/ipv4/conf/eth0/accept_redirects
# echo 0 > /proc/sys/net/ipv4/conf/lo/accept_redirects

こちらも忘れずに。

# echo 1 > /proc/sys/net/ipv4/ip_forward

Openswanでラベル作ろう…

--------
http://www.suz-lab.com

OpenswanとNetScreenとの接続

スズキです。

NetScreenは5GTで、OSのバージョンは"5.0.0r10.1"です。

Openswan側の設定(/etc/ipsec.conf)は、こんな感じです。

--------【ipsec.conf】--------
version 2.0

config setup
  nat_traversal=yes
  virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
  oe=off
  protostack=netkey

conn netscreen
  authby=secret
  left=192.168.11.43
  leftsubnet=192.168.13.0/24
  leftnexthop=%defaultroute
  right=192.168.11.45
  rightsubnet=192.168.1.0/24
  rightnexthop=%defaultroute
  auto=start
  type=tunnel
  auth=esp
  ike=3des-sha1
  phase2alg=3des-sha1
  keyexchange=ike
  ikelifetime=28800s
  keylife=3600s
  pfs=no
--------

NetScreen側の設定は、こんな感じです。

ns5gt-> get config
--------
...
set interface "trust" zone "Trust"
set interface "untrust" zone "Untrust"
set interface "tunnel.1" zone "Trust"
unset interface vlan1 ip
set interface trust ip 192.168.1.1/24
set interface trust route
set interface untrust ip 192.168.11.45/24
set interface untrust route
set interface tunnel.1 ip unnumbered interface trust
set interface untrust gateway 192.168.11.1
unset interface vlan1 bypass-others-ipsec
unset interface vlan1 bypass-non-ip
set interface trust ip manageable
set interface untrust ip manageable
set interface untrust manage telnet
set interface untrust manage web
set interface trust dhcp server service
set interface trust dhcp server auto
set interface trust dhcp server option gateway 192.168.1.1
set interface trust dhcp server option netmask 255.255.255.0
set interface trust dhcp server ip 192.168.1.10 to 192.168.1.20
set flow tcp-mss
set hostname ns5gt
set address "Trust" "192.168.1.0/24" 192.168.1.0 255.255.255.0
set address "Untrust" "192.168.13.0/24" 192.168.13.0 255.255.255.0
set ike gateway "Gateway for 192.168.13.0/24" address 192.168.11.43
Main outgoing-interface "untrust" preshare "XXXXXXXX" sec-level
compatible
unset ike policy-checking
set ike respond-bad-spi 1
set vpn "VPN for 192.168.13.0/24" gateway "Gateway for
192.168.13.0/24" replay tunnel idletime 0 sec-level compatible
set vpn "VPN for 192.168.13.0/24" id 1 bind interface tunnel.1
set pki authority default scep mode "auto"
set pki x509 default cert-path partial
set policy id 3 from "Untrust" to "Trust" "192.168.13.0/24"
"192.168.1.0/24" "ANY" permit
set policy id 2 from "Trust" to "Untrust" "192.168.1.0/24"
"192.168.13.0/24" "ANY" permit
set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" permit
set global-pro policy-manager primary outgoing-interface untrust
set global-pro policy-manager secondary outgoing-interface untrust
set vrouter "untrust-vr"
set vrouter "trust-vr"
unset add-default-route
set route 192.168.13.0/24 interface tunnel.1
...
--------

ポイントは"unset ike policy-checking"です。これをやっておかないと、
NetScreen側で下記のエラーが出力され、接続に失敗します。

Rejected an IKE packet on untrust from 192.168.11.43:500 to 192.168.11.45:500
with cookies xxxxxxxx and xxxxxxxx because the peer sent a proxy ID
that did not match the one in the SA config.

次はEC2上のOpenswanとの接続です…

--------
http://www.suz-lab.com

2010年6月15日火曜日

"Tab Mix Plus"でタブの固定(Firefox)

スズキです。

"Google Chrome"のタブ固定機能が地味に便利だったので、
Firefoxでもできなか、と思い調べてみたら、
"Tab Mix Plus"というアドオンに行き着きました。
https://addons.mozilla.org/ja/firefox/addon/1122/

インストール後に、該当タブをクリックして、
「タブを保護」と「タブをロック」を有効にすると、
"Google Chrome"のようにタブ固定ができます。

ちなみに「タブを保護」と「タブをロック」は、
こちらで詳しく説明されています。
http://smallsteps06.blogspot.com/2006/09/tab-mix-plus.html

> タブを保護: 保護されたタブは閉じられない. タブを誤って閉じるのを防ぐ
> タブをロック: ロックされたタブ内のリンクはすべて新しいタブに開く.

でも、メインブラウザはChrome…

--------
http://www.suz-lab.com

UINavigationControllerのツールバーにボタンを追加

スズキです。

かなりハマったのですが、結局、UIViewControllerの
"setToolbarItems"を使うってことでした…

コードはこんな感じです。

--------【Objective-C】--------
- (void)viewDidLoad {
  [super viewDidLoad];
  UIBarButtonItem *button = [[UIBarButtonItem alloc]
      initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
      target:nil
      action:nil];
  [self setToolbarItems:[NSArray arrayWithObjects:button, nil] animated:NO];
  [button release];
  [self.navigationController setToolbarHidden:NO animated:NO];
}
--------
※UINavigationControllerのRootViewになってることが前提です

そろそろ、体重記録ツールでも作ろう...

--------
http://www.suz-lab.com

2010年6月14日月曜日

簡単なUITableViewControllerのサブクラス

スズキです。

"Interface Builder"を使わなくなった、今日、この頃です。

最低限、下記のような感じで作っておくと、
とりあえず、表が表示されます。

--------【MyTableViewController.h】--------
#import <UIKit/UIKit.h>

// UITableViewControllerを継承
@interface MyTableViewController : UITableViewController {
}

@end
--------

--------【MyTableViewController.m】--------
#import "MyTableViewController.h"

@implementation MyTableViewController

- (id)initWithStyle:(UITableViewStyle)style {
  if ((self = [super initWithStyle:style])) {
    // テーブルのタイトル
    self.title = @"My Table View Controller";
    // テーブルの背景色
    self.view.backgroundColor = [UIColor blackColor];
  }
  return self;
}

// セクションの数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  return 2;
}

// 各セクションのセルの数
- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
  return 2;
}

// 各セクションのタイトル
- (NSString *)tableView:(UITableView *)tableView
    titleForHeaderInSection:(NSInteger)section {
  return @"My Table View Controller";
}

// セルの作成
- (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
        reuseIdentifier:CellIdentifier] autorelease];
  }
  return cell;
}

@end
--------

あとは、どこかで、

[[MyTabViewController alloc] initWithStyle:UITableViewStylePlain]

で利用することになります。

とりあえず、テーブルを極めよう…

--------
http://www.suz-lab.com

Objective-Cで配列の繰り返し処理

スズキです。

こんな感じで書くことができます。

--------【Objective-C】--------
NSArray *array = [NSArray arrayWithObjects:@"aaa", @"bbb", @"ccc", nil];
for (NSString *string in array) {
  NSLog(string);
}
--------

"Interface Builder"は使わない方がやりやすいかも…

--------
http://www.suz-lab.com

2010年6月11日金曜日

Openswanの"ipsec.conf"の"auto"

スズキです。

"auto=add"にすると接続待ちで起動、"auto=start"にすると、
もう一方のVPNゲートウェイに起動時に接続しにいくようになります。

ですので、下記のような場合は、
http://blog.suz-lab.com/2010/06/openswanipsec.html
一方の"ipsec.conf"を"auto=add"に、もう一方を"auto=start"にして、
"auto=start"のOpenswanを後に起動するようにします。

今日中に"Openswan - Netscreen"、がんばろう。

--------
http://www.suz-lab.com

OpenswanでIPsec(たぶん一番簡単な方法)

スズキです。

下記構成のVPNの実現です。

A-CLIENT --- A-GATEWAY ---(VPN)--- B-GATEWAY --- B-CLIENT
A-CLIENT: 192.168.12.2
A-GATEWAY: 192.168.12.1, 192.168.11.41
B-GATEWAY: 192.168.13.1, 192.168.11.43
B-CLIENT: 192.168.13.2

上記構成でOpenswanを利用して、
IPsecによりA-CLIENTからB-CLIENTへVPN接続できるようにします。

まず両GATEWAYに、下記で紹介したようにOpenswanを導入します。
http://blog.suz-lab.com/2010/06/ec2-l2tpipsec-iphone_02.html

次に設定ですが、こちらも両GATEWAY、同じ設定をします。

--------【ipsec.secrets】--------
: PSK "vpn"
--------
※両サーバ共通です。

--------【ipsec.conf】--------
version 2.0
config setup
  nat_traversal=yes
  virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
  oe=off
  protostack=netkey
conn sample
  authby=secret
  left=192.168.11.41
  leftsubnet=192.168.12.0/24
  leftnexthop=%defaultroute
  right=192.168.11.43
  rightsubnet=192.168.13.0/24
  rightnexthop=%defaultroute
  auto=add
--------
※authby: "secret"と"rsasig"が指定できますが、"secretです。
※left: もう一方のVPN-GATEWAYに繋がってるIFのアドレスです。
※leftsubnet: ローカルのサブネットです。
※right: もう一方のVPN-GATEWAYに繋がってるIFのアドレスです。
※rightsubnet: ローカルのサブネットです。
※auto=add

これでOpenswanは起動するはずですが、正常に動作させるためには、
下記のコマンド結果からFAILEDをなくさなければいけません。

# ipsec verify
--------
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path [OK]
Linux Openswan U2.6.26/K2.6.18-194.3.1.el5.centos.plus (netkey)
Checking for IPsec support in kernel [OK]
Testing against enforced SElinux mode [FAILED]
SElinux is running in 'enforced' mode.
If you encounter network related SElinux errors, especially when using KLIPS,
try disabling SElinux using:
echo "0" > /selinux/enforce (or edit /etc/sysconfig/selinux)
NETKEY detected, testing for disabled ICMP send_redirects [FAILED]
Please disable /proc/sys/net/ipv4/conf/*/send_redirects
or NETKEY will cause the sending of bogus ICMP redirects!
NETKEY detected, testing for disabled ICMP accept_redirects [FAILED]
Please disable /proc/sys/net/ipv4/conf/*/accept_redirects
or NETKEY will accept bogus ICMP redirects!
Checking for RSA private key (/etc/ipsec.secrets) [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [FAILED]
Cannot execute command "lsof -i UDP:500": そのようなファイルやディレクトリはありません
Pluto listening for NAT-T on udp 4500 [FAILED]
Cannot execute command "lsof -i UDP:4500": そのようなファイルやディレクトリはありません
Two or more interfaces found, checking IP forwarding [FAILED]
Cannot execute command "lsof -i UDP:4500": そのようなファイルやディレクトリはありません
Checking for 'ip' command [OK]
Checking for 'iptables' command [OK]
Opportunistic Encryption Support [DISABLED]
--------

ということで、ひとつずつ解決していきます。

========
Testing against enforced SElinux mode [FAILED]
--------
SElinux is running in 'enforced' mode.
If you encounter network related SElinux errors, especially when using KLIPS,
try disabling SElinux using:
echo "0" > /selinux/enforce (or edit /etc/sysconfig/selinux)
========

SElinuxを無効にしなければいけないので、
"/etc/sysconfig/selinux"を下記のように調整します。

--------【selinux】--------
...
SELINUX=disabled
...
--------

========
NETKEY detected, testing for disabled ICMP send_redirects [FAILED]
--------
Please disable /proc/sys/net/ipv4/conf/*/send_redirects
or NETKEY will cause the sending of bogus ICMP redirects!
========
NETKEY detected, testing for disabled ICMP accept_redirects [FAILED]
--------
Please disable /proc/sys/net/ipv4/conf/*/accept_redirects
or NETKEY will accept bogus ICMP redirects!
========

下記のように、"/etc/sysctl.conf"を調整します。

--------【sysctl.conf】--------
...
net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.eth1.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.eth1.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
...
--------

========
Pluto listening for IKE on udp 500 [FAILED]
Cannot execute command "lsof -i UDP:500": そのようなファイルやディレクトリはありません
Pluto listening for NAT-T on udp 4500 [FAILED]
Cannot execute command "lsof -i UDP:4500": そのようなファイルやディレクトリはありません
Two or more interfaces found, checking IP forwarding [FAILED]
Cannot execute command "lsof -i UDP:4500": そのようなファイルやディレクトリはありません
========

"lsof"コマンドが無いということなので、下記でインストールです。

# yum install lsof

この状態でリブートして再度確認すると、
下記のようにFAILEDが無くなっているのがわかります。

# ipsec verify
--------
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path [OK]
Linux Openswan U2.6.26/K2.6.18-194.3.1.el5.centos.plus (netkey)
Checking for IPsec support in kernel [OK]
NETKEY detected, testing for disabled ICMP send_redirects [OK]
NETKEY detected, testing for disabled ICMP accept_redirects [OK]
Checking for RSA private key (/etc/ipsec.secrets) [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [OK]
Pluto listening for NAT-T on udp 4500 [OK]
Two or more interfaces found, checking IP forwarding [OK]
Checking NAT and MASQUERADEing [N/A]
Checking for 'ip' command [OK]
Checking for 'iptables' command [OK]
Opportunistic Encryption Support [DISABLED]
--------

最後に、A-CLIENTからB-CLIENTに"ping"すると、
ちゃんと通じていることが確認できます。

次は、Netscreenと接続だ...
--------
http://www.suz-lab.com

2010年6月10日木曜日

ディレクトリ内のファイルやディレクトリを順番に取得(iPhone)

スズキです。

配列での取得は、下記で紹介しました。
http://blog.suz-lab.com/2010/06/iphone.html

今回は順番に取得する方法です。
下記のように、NSDirectoryEnumeratorで取得します。

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docDir = [NSHomeDirectory()
stringByAppendingPathComponent:@"Documents"];
NSDirectoryEnumerator *files = [fileManager enumeratorAtPath:docDir];

順番に取得するには、nextObjectメソッドを利用します。

NSString *fileName = [files nextObject];

実際には、取得した画像ファイル群を
タイマー使ってスライドショー的に表示するのに利用しています。
(ソースは下記のような感じです)

▼ViewerViewController.h
http://code.google.com/p/suz-lab-ios/source/browse/trunk/CaptureCamera/Classes/ViewerViewController.h?r=6

▼ViewerViewController.m
http://code.google.com/p/suz-lab-ios/source/browse/trunk/CaptureCamera/Classes/ViewerViewController.m?r=6

Objective-Cにも慣れてきたかなー...

--------
http://www.suz-lab.com

AssemblaでプライベートSVN

スズキです。

iPhone/iPadの開発環境本格化の一環として、
ソースはSVNで管理することにしたのですが、
Publicなものは、いつもの"Google Code"で良いのですが、
http://code.google.com/p/suz-lab-ios/
Privateのものも欲しいなーと思い、いろいろ調べてみました。

そして、最終的には下記のAssemblaを利用することにしました。
http://www.assembla.com/

こちらにプランの説明があり、"Free Repositories"は次の通りです。
http://www.assembla.com/plans

- Unlimited users
- Unlimited spaces
- 2 GB
- SVN and GIT Repositories Only
- Private - Only visible to your team members

ということで、 Public/PrivateのSVNも用意できたので、
次は、Testと CIあたりかなー...

--------
http://www.suz-lab.com

iPhoneアプリを横向きに起動

スズキです。

"Xxx-info.plist" を編集する必要があります。

上記ファイルのKeyに"Initial interface orientation"を追加します。

Valueには下記が選択できるので、

- Portrait(bottom home button)
- Portrait(top home button)
- Landscape(left home button)
- Landscape(right home button)

ホームボタンをが右の横向きで起動したい場合は、
"Landscape(right home button)"を選択します。

iPhone/iPad開発環境が本格的になってきた...

--------
http://www.suz-lab.com

2010年6月9日水曜日

VPC(beta)の制限

スズキです。

下記の"Beta Limitations"、そのままですが...
http://aws.amazon.com/vpc/#details

> One (1) VPC per AWS account
> Twenty (20) subnets per VPC
> One (1) VPN gateway per AWS account
> One (1) VPN connection per VPN gateway
> One (1) customer gateway per AWS account

とのことです。

上限を増やしたい場合は、こちらのフォームからリクエストできます。
http://aws.amazon.com/contact-us/vpc-request/

近頃、AWS+への問い合わせが多いなー...

--------
http://www.suz-lab.com

Postfixでメールを残しながら転送(aliases)

スズキです。

いろいろとやり方はあると思いますが、
"/etc/aliases"を利用した方法です。

root宛のメールをsuzuki@suz-lab.comに転送して、
rootにもメールを残すには、"/etc/aliases"を下記のようにします。

--------【aliases】--------
...
root: suzuki@suz-lab.com,root
--------

反映は、下記コマンドで行います。

# newaliases

ブログの更新頻度が落ちてる…

--------
http://www.suz-lab.com

2010年6月7日月曜日

ディレクトリ内のファイルやディレクトリを取得(iPhone)

スズキです。

NSFileManagerを使います。

--------【Objective-C】--------
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docDir = [NSHomeDirectory()
stringByAppendingPathComponent:@"Documents"];
NSArray *images = [fileManager directoryContentsAtPath:docDir];
NSLog([images description]);
--------

逆引きリファレンスみたいになってきた…

--------
http://www.suz-lab.com

UIGetScreenImageでキャプチャーした画像を保存(iPhone)

スズキです。

コードは、こんな感じです。

--------【Objective-C】--------
NSData *capture = UIImageJPEGRepresentation(
  [UIImage imageWithCGImage:UIGetScreenImage()], 1.0
);
NSString *docDir = [
  NSHomeDirectory() stringByAppendingPathComponent:@"Documents"
];
NSString *filePath = [
  NSString stringWithFormat:@"%@/%@%02d.jpg", docDir, self.filename, count - 20
];
if ([capture writeToFile:filePath atomically:YES]) {
  NSLog(@"OK %@", filePath);
} else {
  NSLog(@"NG %@", filePath);
}
--------

まず、UIGetScreenImageした画像をUIImageにして、その後JPEGのNSDataにします。
そして、保存先のパス($HOME/Documents/以下)を作成し、
NSDataのwriteToFileメソッドで保存します。

iPadアプリにも挑戦しよう。

--------
http://www.suz-lab.com

2010年6月2日水曜日

CentOS 5.5

スズキです。

# yum update

したら、下記のようになってました。

# cat /etc/redhat-release
CentOS release 5.5 (Final)

AMIも5.5ベースのものにしないとなー…

--------
http://www.suz-lab.com

EC2 & L2TP/IPsec & iPhone

スズキです。

EC2でOpenswanが利用できるかの確認もかねて、
iPhoneでVPN接続できる環境を構築してみました。

EC2上には、下記のCentOS(64bit)を利用し、
http://blog.suz-lab.com/2010/04/suz-lab-centos-ami-549.html
IPsecには以下の"Openswan"、
http://www.openswan.org/
L2TP
には以下の"xl2tpd"を利用しています。
http://www.xelerance.com/software/xl2tpd/

まずはインストールです。

"Openswan"のインストールは、下記のとおりです。
(最新ソースからのインストールとしています)
# yum install make gcc gmp-devel bison flex
# curl -OL http://www.openswan.org/download/openswan-2.6.26.tar.gz
# tar xvzf openswan-2.6.26.tar.gz
# make programs install

"xl2tpd"のインストールは、次のように"yum"で行います。
# yum install xl2tpd

次に、Openswanの設定で、設定ファイルは、
"/etc/ipsec.conf"、"/etc/ipsec.secrets"、"/etc/ipsec.d/l2tp-psk.conf"
となり、以下のようにしています。

--------【ipsec.conf】--------
version 2.0
config setup
  nat_traversal=yes
  virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
  oe=off
  protostack=netkey
include /etc/ipsec.d/*.conf
--------
ほぼ、デフォルト通りです。

--------【ipsec.secrets】--------
: PSK "pre-shared-key"
--------
"pre-shared-key"は任意の文字列で、iPhoneにも入力する内容です。

--------【ipsec.conf】--------
conn L2TP-PSK-NAT
  rightsubnet=vhost:%priv
  also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
  authby=secret
  pfs=no
  auto=add
  keyingtries=3
  rekey=no
  ikelifetime=8h
  keylife=1h
  type=transport
  left=10.160.x.y
  leftprotoport=17/1701
  right=%any
  rightprotoport=17/0
conn passthrough-for-non-l2tp
  type=passthrough
  left=10.160.x.y
  leftnexthop=10.160.z.1
  right=0.0.0.0
  rightsubnet=0.0.0.0/0
  auto=route
--------
"left"には、EC2に割り振られたプライベートIP、
"leftnexthop"にはそのデフォルトゲートウェイを指定します。

そして、"xl2tpd"の設定は、"/etc/xl2tpd/xl2tpd.conf"、"/etc/ppp/chap-secrets"
"/etc/ppp/options.xl2tpd"で行います。

--------【xl2tpd.conf】--------
[global]
[lns default]
ip range = 192.168.2.128-192.168.2.254
local ip = 192.168.2.1
require chap = yes
refuse pap = yes
require authentication = yes
name = LinuxVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
--------
"ip range"はVPNクライアントに割り振るIPアドレスの範囲、
"local ip"はVPNサーバのIPアドレスです。

--------【chap-secrets】--------
user * "password" *
--------
ユーザーとパスワードを定義します。iPhoneの入力項目でもあります。

--------【options.xl2tpd】--------
ipcp-accept-local
ipcp-accept-remote
ms-dns 192.168.2.1
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
logfile /var/log/xl2tpd.l2tp-ipsec.log
--------
"ms-dns"でDNSとなるIPアドレスを指定します。

この状態で、"Openswan"と"xl2tpd"を起動すれば、サーバの設定は終了です。
# /etc/init.d/ipsec start
# /etc/init.d/xl2tpd start

最後に、AWSのセキュリティーグループで、
UDPの1701番と500番と4500番を許可すれば、iPhoneからEC2にVPN接続できるようになります。

iPhoneの設定に関しては、
「設定」 → 「一般」 → 「ネットワーク」 → 「VPN」 → 「VPN構成を追加」で、「L2TP」を選択して、

説明: 適当に
サーバ: 上記サーバ(Public IP)
アカウント: user ("chap-secrets"の内容)
RSA SecureID: オフ
パスワード: password ("chap-secrets"の内容)
シークレット: pre-shared-key ("ipsec.secrets"の内容)
すべての信号を送信: オン

と入力しておけば、OKです。

次はNetScreenとつなげないと...

--------
http://www.suz-lab.com

2010年6月1日火曜日

ProFTPDでドットファイルを表示

スズキです。

デフォルト設定だと非表示になっています。

"/etc/proftpd.conf"に下記記述を入れることで、表示するようになります。

--------【proftpd.conf】--------
...
ListOptions "-a"
--------

iPhoneとVPNが同時進行…

--------
http://www.suz-lab.com

UIGetScreenImageでカメラ画像のキャプチャー(iPhone)

スズキです。

UIImagePickerControllerでカメラ表示までできたので、
http://blog.suz-lab.com/2010/05/uiimagepickercontrolleriphone.html

次は、そのカメラ画像のキャプチャーです。

キャプチャー時には、最初の二秒くらいは、シャッターアニメーションなので、
タイマーで、それ以降にキャプチャーするように調整擦る必要があります。

コードは下記のようになりました。
(UIGetScreenImageViewController.hは下記のものと同じです)
http://blog.suz-lab.com/2010/05/uiimagepickercontrolleriphone.html

タイマーで、二秒後から、0.5秒ごとに5枚キャプチャーしています。

--------【UIGetScreenImageViewController.m】--------
#import "UIGetScreenImageViewController.h"
@implementation UIGetScreenImageViewController

NSInteger captureCount;
NSTimer* timer;
UIImagePickerController* imagePicker;

- (void)viewDidLoad {
  [super viewDidLoad];
  imagePicker = [[UIImagePickerController alloc] init];
  imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
  imagePicker.showsCameraControls = NO;
  [imagePicker autorelease];
}

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  [self presentModalViewController:imagePicker animated:YES];
  captureCount = 0;
  timer = [NSTimer
    scheduledTimerWithTimeInterval:0.5
    target:self
    selector:@selector(onTimer:)
    userInfo:nil
    repeats:YES
  ];
}

- (void)onTimer:(NSTimer *)timer {
  if(captureCount <= 8) {
    if(captureCount >= 4) {
      UIImageWriteToSavedPhotosAlbum(
        [UIImage imageWithCGImage:UIGetScreenImage()],
        nil,
        nil,
      nil);
      NSLog(@"%d", captureCount);
    }
  } else {
    [timer invalidate];
  }
 captureCount++;
}

@end
--------

[self dismissModalViewControllerAnimated:YES];
でカメラ消そうとしたら、「EXC_BAD_ACCESS」になってしまう…

--------
http://www.suz-lab.com