<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>RubberEgg</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/" />
    <link rel="self" type="application/atom+xml" href="http://journal.reallyenglish.com/atom.xml" />
    <id>tag:journal.reallyenglish.com,2008-10-31://1</id>
    <updated>2011-09-29T10:50:04Z</updated>
    <subtitle>notes on software development and online education by reallyenglish team.</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.31-en</generator>

<entry>
    <title>make release on OpenBSD and FreeBSD</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2011/09/29/make-release-on-openbsd-and-freebsd.html" />
    <id>tag:journal.reallyenglish.com,2011://1.33</id>

    <published>2011-09-29T10:07:34Z</published>
    <updated>2011-09-29T10:50:04Z</updated>

    <summary>We&#8217;ve been creating our own release for some time. Every new release or bugfix release, I just ssh to build servers and &#8220;make&#8221;. Here is what I wrote to release the latest version of OpenBSD and FreeBSD. Most of defaults...</summary>
    <author>
        <name>Tomoyuki Sakurai</name>
        
    </author>
    
        <category term="FreeBSD" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="OpenBSD" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>We&#8217;ve been creating our own release for some time. Every new release or bugfix release, I just ssh to build servers and &#8220;make&#8221;. Here is what I wrote to release the latest version of OpenBSD and FreeBSD. Most of defaults are reasonably defined for many, but please grep &#8220;changeme&#8221; the Makefiles below and change the values. See release(8) for OpenBSD, release(7) for FreeBSD.</p>

<h2>OpenBSD</h2>

<p>The Makefile does the same thing documented at <a href="http://openbsd.com/faq/faq5.html#Release" title="5.4 - Building a Release">5.4 - Building a Release</a> in the FAQ.</p>

<p>Create /etc/src.supfile to update src. Change the tag to which release you want to build. In this example, it&#8217;s OPENBSD<em>4</em>9.</p>

<pre><code>*default release=cvs tag=OPENBSD_4_9
*default delete use-rel-suffix
*default umask=002
*default base=/var/db
*default prefix=/usr
OpenBSD-src
</code></pre>

<p>Install csup by &#8220;pkg<em>add csup&#8221;. Make sure to create a slice for /usr/obj and change DEV</em>OBJ. Also, double check RELEASE<em>ROOT</em>DIR has enough space (1GB is sufficient for 4.9) for all release files. </p>

<pre><code>RELEASE_ROOT_DIR?=  /usr/release
DESTDIR?=           ${RELEASE_ROOT_DIR}/dest
RELEASEDIR?=        ${RELEASE_ROOT_DIR}/rel
CVSUP_HOST?=        changeme.cvsup.example.org
SRCDIR?=            /usr/src
OBJDIR?=            /usr/obj
# XXX this Makefile assumes ${OBJDIR} is on a dedicated slice
DEV_OBJ?=           /changeme/dev/rwd0g
SUPFILE?=           /etc/src.supfile
PATCHE_FILES?=
PATCHFLAGS?=
CONFIG?=            GENERIC

all: update patch buildkernel buildworld release checkflist make-index

init:
    pkg_add csup
    mkdir -p ${DESTDIR} ${RELEASEDIR}
    @echo "make init finished successfully"
    @echo "please create ${SUPFILE} for your own."
    @echo "make sure to create base dir for csup (*default base=/var/db)"

update:
    /usr/local/bin/csup -h ${CVSUP_HOST} -gsL2 ${SUPFILE}

patch:
.for P in ${PATCHES_FILES}
    (cd ${SRCDIR} &amp;&amp; patch ${PATCHFLAGS} &lt; ${P})
.endfor

buildkernel:
    (cd ${SRCDIR}/sys/arch/`uname -m`/conf &amp;&amp; config ${CONFIG})
    (cd ${SRCDIR}/sys/arch/`uname -m`/conf/../compile/${CONFIG} &amp;&amp; make clean &amp;&amp; make depend &amp;&amp; make &amp;&amp; make install)

buildworld: clean-obj make-obj
    (cd ${SRCDIR}/etc &amp;&amp; env DESTDIR=/ make distrib-dirs)
    (cd ${SRCDIR} &amp;&amp; make build)

make-obj:
    (cd ${SRCDIR} &amp;&amp; make obj BSDSRCDIR=${SRCDIR} BSDOBJDIR=${OBJDIR})

clean-obj:
    umount ${OBJDIR} || true
    newfs  ${DEV_OBJ}
    mount ${OBJDIR}

clean-destdir:
    test -d ${DESTDIR} &amp;&amp; mv ${DESTDIR} ${DESTDIR}.old &amp;&amp; rm -rf ${DESTDIR}.old &amp;
    mkdir -p ${DESTDIR} ${RELEASEDIR}

release: clean-destdir
    (cd ${SRCDIR}/etc  &amp;&amp; make release DESTDIR=${DESTDIR} RELEASEDIR=${RELEASEDIR})

checkflist:
    (cd ${SRCDIR}/distrib/sets &amp;&amp; export DESTDIR=${DESTDIR} &amp;&amp; sh checkflist)

make-index:
    (cd ${RELEASEDIR} &amp;&amp; /bin/ls -1 &gt;index.txt)
</code></pre>

<h2>FreeBSD</h2>

<p>As our FreeBSD nodes are mix of several release branch, the Makefile supports multiple releases. It also supports uploading the images to server, possibly useful for pxeboot server. Install git and subversion by running &#8220;pkg_add -r subversion git&#8221;. Then, &#8220;make init&#8221;.</p>

<pre><code># FreeBSD release(8) Makefile
#
# to initilize, "make init".
#
# * create all directories
# * checkout all sources
#
# "make all" creates release ISO and FTP directories for all
# FreeBSD $RELEASE_MAJOR.$RELEASE_MINOR_VERSIONS
#
# "make update-stable release-stable" creates one for -STABLE
#
# SEE ALSO
#   http://www.freebsd.org/doc/en/articles/releng/index.html (outdated but still useful)
#   release(7)
#   /usr/src/release/Makefile 

RELEASE_DIR?=       /usr/home/release
CHROOT_DIR?=        ${RELEASE_DIR}/chroot
RELEASE_MAJOR?=     8
RELEASE_MINOR_VERSIONS?=    2
SVNROOT?=       svn://svn.freebsd.org/base
EXTPORTSDIR?=       /usr/ports
SYSCTL=         /sbin/sysctl
ARCH!=          uname -m
NCPU!=          ${SYSCTL} -n kern.smp.cpus
MAKE_JOBS_NUMBER!=  echo ${NCPU} \* 2 | bc
LOCAL_PATCHES?=
PATCH_FLAGS?=
PXE_HOST?=      changem.pxe.example.org

.if defined(DEBUG)
SVN_FLAGS=
GIT_FLAGS=
.else
SVN_FLAGS=  --quiet
GIT_FLAGS=  --quiet
.endif

GIT!=           which git
SVN!=           which svn
.if !defined(GIT)
    @echo "git not found in PATH." 1&gt;&amp;2
    @echo "please install devel/git" 1&gt;&amp;2 &amp;&amp; exit 1
.endif
.if !defined(SVN)
    @echo "svn not found in PATH." 1&gt;&amp;2
    @echo "please install devel/svn" 1&gt;&amp;2 &amp;&amp; exit 1
.endif

PORTS_GIT_URL=      git://gitorious.org/freebsd/freebsd-ports.git

# release the latest RELEASE branches.
# to release -STABLE, "make update-stable release-stable"
all:    update release

# let's make release faster
#
# * copy local ports (EXTPORTSDIR)
# * do not fetch distfiles every build (RELEASEDISTFILES)
# * create ISO (MAKE_ISOS)
# * use svn (SVNROOT, SVNBRANCH)
# * use multiple cores (WORLD_FLAGS, KERNEL_FLAGS)
# * do not build doc (NODOC)
# * use FTP passive (FTP_PASSIVE_MODE)
release:
.for V in ${RELEASE_MINOR_VERSIONS}
    ${INSTALL} -d ${CHROOT_DIR}/releng/${RELEASE_MAJOR}.${V}
    make -C ${RELEASE_DIR}/sources/releng/${RELEASE_MAJOR}.${V}/src \
        -j${MAKE_JOBS_NUMBER} \
        buildworld
    make -C ${RELEASE_DIR}/sources/releng/${RELEASE_MAJOR}.${V}/src/release \
        release \
        CHROOTDIR=${CHROOT_DIR}/releng/${RELEASE_MAJOR}.${V} \
        RELEASETAG=RELENG_${RELEASE_MAJOR}_${V} \
        BUILDNAME=${RELEASE_MAJOR}.${V}-RELEASE \
        LOCAL_PATCHES="${LOCAL_PATCHES}" \
        PATCH_FLAGS="${PATCH_FLAGS}" \
        EXTPORTSDIR=${EXTPORTSDIR} \
        RELEASEDISTFILES=${EXTPORTSDIR}/distfiles \
        SVNROOT=${SVNROOT} \
        SVNBRANCH=releng/${RELEASE_MAJOR}.${V} \
        WORLD_FLAGS="-j${MAKE_JOBS_NUMBER}" \
        KERNEL_FLAGS="-j${MAKE_JOBS_NUMBER}" \
        MAKE_ISOS=1 NODOC=1 FTP_PASSIVE_MODE=1
.endfor
release-stable:
    ${INSTALL} -d ${CHROOT_DIR}/stable/${RELEASE_MAJOR}
    make -C ${RELEASE_DIR}/sources/stable/${RELEASE_MAJOR}/src \
        -j${MAKE_JOBS_NUMBER} \
        buildworld
    make -C ${RELEASE_DIR}/sources/stable/${RELEASE_MAJOR}/src/release \
        -j ${MAKE_JOBS_NUMBER} \
        release \
        CHROOTDIR=${CHROOT_DIR}/stable/${RELEASE_MAJOR} \
        RELEASETAG=RELENG_${RELEASE_MAJOR} \
        BUILDNAME=${RELEASE_MAJOR}-STABLE \
        LOCAL_PATCHES="${LOCAL_PATCHES}" \
        PATCH_FLAGS="${PATCH_FLAGS}" \
        EXTPORTSDIR=${EXTPORTSDIR} \
        RELEASEDISTFILES=${EXTPORTSDIR}/distfiles \
        SVNROOT=${SVNROOT} \
        SVNBRANCH=stable/${RELEASE_MAJOR} \
        WORLD_FLAGS="-j${MAKE_JOBS_NUMBER}" \
        KERNEL_FLAGS="-j${MAKE_JOBS_NUMBER}" \
        MAKE_ISOS=1 NODOC=1 FTP_PASSIVE_MODE=1

init:   create-dirs checkout checkout-stable checkout-head

create-dirs:
    ${INSTALL} -d ${RELEASE_DIR}/sources
    ${INSTALL} -d ${RELEASE_DIR}/sources/releng
    ${INSTALL} -d ${RELEASE_DIR}/sources/stable
    ${INSTALL} -d ${RELEASE_DIR}/portstrees
    ${INSTALL} -d ${RELEASE_DIR}/chroot
    ${INSTALL} -d ${RELEASE_DIR}/conf
    ${INSTALL} -d ${RELEASE_DIR}/conf/boot

checkout:
.for V in ${RELEASE_MINOR_VERSIONS}
    ${INSTALL} -d ${RELEASE_DIR}/sources/releng/${RELEASE_MAJOR}.${V}
    (cd ${RELEASE_DIR}/sources/releng/${RELEASE_MAJOR}.${V} &amp;&amp; \
        ${SVN} checkout ${SVN_FLAGS} \
        ${SVNROOT}/releng/${RELEASE_MAJOR}.${V} src)
.endfor

checkout-stable:
    ${INSTALL} -d ${RELEASE_DIR}/sources/stable/${RELEASE_MAJOR}
    (cd ${RELEASE_DIR}/sources/stable/${RELEASE_MAJOR} &amp;&amp; \
        ${SVN} checkout ${SVN_FLAGS} \
        ${SVNROOT}/stable/${RELEASE_MAJOR} src)

update:
.for V in ${RELEASE_MINOR_VERSIONS}
    if [ -d ${RELEASE_DIR}/sources/releng/${RELEASE_MAJOR}.${V}/src ]; then \
        (cd ${RELEASE_DIR}/sources/releng/${RELEASE_MAJOR}.${V}/src &amp;&amp; \
            ${SVN} ${SVN_FLAGS} update); \
    else \
        echo "please make checkout first" 1&gt;&amp;2 &amp;&amp; exit 1; \
    fi
.endfor

update-stable:
    if [ -d ${RELEASE_DIR}/sources/stable/${RELEASE_MAJOR}/src ]; then \
        (cd ${RELEASE_DIR}/sources/stable/${RELEASE_MAJOR}/src &amp;&amp; \
            ${SVN} ${SVN_FLAGS} update); \
    else \
        echo "please make checkout-stable first" 1&gt;&amp;2 &amp;&amp; exit 1; \
    fi

clone-ports:
    (cd ${RELEASE_DIR}/portstrees &amp;&amp; \
        ${GIT} clone ${GIT_FLAGS} ${PORTS_GIT_URL})

pull-ports:
    if [ -d ${RELEASE_DIR}/portstrees/freebsd-ports ]; then \
        (cd ${RELEASE_DIR}/portstrees/freebsd-ports &amp;&amp; \
            ${GIT} pull ${GIT_FLAGS}); \
    else \
        @echo "please make clone-ports first" 1&gt;&amp;2 &amp;&amp; exit 1; \
    fi

# two targets to get HEAD sources.
# no release-head target because we don't need it.
# also, building HEAD on non-HEAD is not supported.
# use snapshot or build HEAD on your own host.
checkout-head:
    (cd ${RELEASE_DIR}/sources &amp;&amp; \
        ${SVN} checkout ${SVN_FLAGS} ${SVNROOT}/head head)

update-head:
    (cd ${RELEASE_DIR}/sources/head &amp;&amp; ${SVN} ${SVN_FLAGS} update)

upload:
.for V in ${RELEASE_MINOR_VERSIONS}
    # XXX [KNOWN BUG] gzipped mfsroot doesn't work
    if [ -f ${RELEASE_DIR}/chroot/releng/${RELEASE_MAJOR}.${RELEASE_MINOR_VERSIONS}/R/cdrom/disc1/boot/mfsroot.gz ]; then \
        gunzip ${RELEASE_DIR}/chroot/releng/${RELEASE_MAJOR}.${RELEASE_MINOR_VERSIONS}/R/cdrom/disc1/boot/mfsroot.gz ; \
    fi
    ssh ${PXE_HOST} \
        rm -rf /tftproot/pub/FreeBSD/${ARCH}/${RELEASE_MAJOR}.${RELEASE_MINOR_VERSIONS}-RELEASE
    scp -r \
        ${RELEASE_DIR}/chroot/releng/${RELEASE_MAJOR}.${RELEASE_MINOR_VERSIONS}/R/cdrom/disc1 \
        ${PXE_HOST}:/tftproot/pub/FreeBSD/${ARCH}/${RELEASE_MAJOR}.${RELEASE_MINOR_VERSIONS}-RELEASE
    # copy loader.conf for pxeboot
    scp ${RELEASE_DIR}/conf/boot/* \
        ${PXE_HOST}:/tftproot/pub/FreeBSD/${ARCH}/${RELEASE_MAJOR}.${RELEASE_MINOR_VERSIONS}-RELEASE/boot/
.endfor
</code></pre>
]]>
        

    </content>
</entry>

<entry>
    <title>Making VPN connection to OpenBSD with iPhone 4</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2011/05/13/making-vpn-connection-to-openbsd-with-iphone-4.html" />
    <id>tag:journal.reallyenglish.com,2011://1.32</id>

    <published>2011-05-13T04:09:23Z</published>
    <updated>2011-05-21T09:04:56Z</updated>

    <summary>iPhone 4 is able to make VPN connection and send all traffic through it, which is useful when you use public WiFi and/or need intranet resources. Installing OpenBSD 4.9 See the FAQ. You need to install the kernel and userland...</summary>
    <author>
        <name>Tomoyuki Sakurai</name>
        
    </author>
    
        <category term="Networking" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="OpenBSD" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Security" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>iPhone 4 is able to make VPN connection and send all traffic through it, which is useful when you use public WiFi and/or need intranet resources.</p>

<h1>Installing OpenBSD 4.9</h1>

<p>See <a href="http://www.openbsd.org/faq/index.html">the FAQ</a>. You need to install the kernel and userland sources as well to build npppd and PIPEX kernel.</p>

<h1>Building PIPEX kernel and installing npppd</h1>

<p>At the time of this writing, npppd is not installed by default. npppd requires "option PIPEX" in kernel config file, which is not enabled by default. Follow the instruction in /usr/src/usr.sbin/npppd/HOWTO_PIPEX_NPPPD.txt after you extract the source code. Note that amd64 users need to patch npppd at the moment. The patch below was from the author. Patch at your own risk.</p>

<pre><code>&gt; cd &amp;&amp; fetch http://journal.reallyenglish.com/2011/05/13/privsep.diff.txt
&gt; cd /usr/src/usr.sbin/npppd/npppd
&gt; sudo patch &lt; ~/privsep.diff.txt
</code></pre>

<h1>npppd.conf</h1>

<h2>Networking</h2>

<pre><code>interface_list: tun1
interface.tun1.ip4addr: $ip.add.re.ss
pool.dyna_pool: $ip.add.re.ss/$subnet
lcp.mru: 1400
ipcp.dns_primary: $dns.add.re.ss
</code></pre>

<h2>Authentication</h2>

<p>Choose authentication method. CSV file is good for testing.</p>

<pre><code>auth.method: mschapv2 chap
auth.local.realm_list: local
auth.local.realm.acctlist: /etc/npppd/npppd-users.csv
realm.local.concentrate: tun1
</code></pre>

<p>Create a CSV file, /etc/npppd/npppd-users.csv which looks like:</p>

<pre><code>Username,Password,Framed-IP-Address,Framed-IP-Netmask,Description,Calling-Id
user,secret,$ip.add.re.ss,,memo for user
</code></pre>

<p>If you have working RADIUS server,</p>

<pre><code>auth.radius.realm_list: radius
auth.radius.realm.server.address: 127.0.0.1
auth.radius.realm.server.secret: $radius_secret
realm.radius.concentrate: tun1
</code></pre>

<p>Note that you need clear text password or NT password in the RADIUS backend when mschapv2 is used.</p>

<h2>VPN protocol</h2>

<p>Choose VPN protocol.</p>

<pre><code>pptpd.enabled: true
pptpd.ip4_allow: 0.0.0.0/0
</code></pre>

<h2>Connecting to npppd</h2>

<p>Run npppd in debug mode.</p>

<pre><code># npppd -d
2011-05-21 17:54:03:NOTICE: Starting npppd pid=30068 version=5.0.0                                               
2011-05-21 17:54:03:NOTICE: Load configuration from='/etc/npppd/npppd.conf' successfully.
2011-05-21 17:54:03:WARNING: write() failed in in_route0 on RTM_ADD : File exists
2011-05-21 17:54:03:INFO: tun1 Started ip4addr=10.103.0.1
2011-05-21 17:54:03:INFO: pool name=default dyn_pool=[10.103.0.0/25] 
2011-05-21 17:54:03:INFO: Added 1 routes for new pool addresses
2011-05-21 17:54:03:INFO: Loading pool config successfully.
2011-05-21 17:54:03:INFO: realm name=radius(radius) Loaded configuration timeout=9 nserver=1
2011-05-21 17:54:03:INFO: Listening /var/run/npppd_ctl (npppd_ctl)
2011-05-21 17:54:03:INFO: l2tpd Listening 0.0.0.0:1701/udp (L2TP LNS) [L2TP]
2011-05-21 17:54:03:INFO: l2tpd Listening [::]:1701/udp (L2TP LNS) [L2TP]
2011-05-21 17:54:03:INFO: pptpd Listening 0.0.0.0:1723/tcp (PPTP PAC) [PPTP]
2011-05-21 17:54:03:INFO: pptpd Listening 0.0.0.0:gre (PPTP PAC)
2011-05-21 17:54:03:INFO: tun1 is using ipcp=default(1 pools).
</code></pre>

<p>When everything works, you will see:</p>

<pre><code>2011-05-21 17:58:00:NOTICE: ppp id=1 layer=base logtype=TUNNELSTART user="user" duration=3sec layer2=PPTP layer2from=211.19.48.10:16749 auth=MS-CHAP-V2  ip=10.103.0.9 iface=tun1
2011-05-21 17:58:00:NOTICE: ppp id=1 layer=base Using pipex=yes
</code></pre>
]]>
        

    </content>
</entry>

<entry>
    <title>We are looking for a senior rails web developer in Tokyo</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2010/08/13/we-are-looking-for-a-senior-rails-web-developer-in-tokyo.html" />
    <id>tag:journal.reallyenglish.com,2010://1.31</id>

    <published>2010-08-13T13:33:53Z</published>
    <updated>2010-10-07T00:56:22Z</updated>

    <summary>See: http://www.reallyenglish.com/company/recruiting/index.html...</summary>
    <author>
        <name>Masatomo Nakano</name>
        <uri>http://twitter.com/masatomon</uri>
    </author>
    
        <category term="News / Announcements" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>See:  <a href="http://www.reallyenglish.com/company/recruiting/index.html">http://www.reallyenglish.com/company/recruiting/index.html</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>ModSecurity with gzip by FilterChain and ExtFilterDefine</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2010/03/02/modsecurity-with-gzip-by-filterchain-and-extfilterdefine.html" />
    <id>tag:journal.reallyenglish.com,2010://1.30</id>

    <published>2010-03-01T15:05:59Z</published>
    <updated>2010-03-26T01:11:43Z</updated>

    <summary>UPDATE: Ivan Ristic implemented SecDisableBackendCompression in trunk. With this directive, you don&#8217;t need the hack below. See my post to the list. One of cryptic warnings found in ModSecurity audit.log is [msg &quot;ModSecurity does not support content encodings&quot;] Clearly, it...</summary>
    <author>
        <name>Tomoyuki Sakurai</name>
        
    </author>
    
        <category term="Security" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>UPDATE: Ivan Ristic implemented SecDisableBackendCompression in trunk. With this directive, you don&#8217;t need the hack below. See <a href="http://article.gmane.org/gmane.comp.apache.mod-security.user/7351">my post to the list</a>.</p>

<p>One of cryptic warnings found in ModSecurity audit.log is</p>

<pre><code>  [msg "ModSecurity does not support content encodings"]
</code></pre>

<p>Clearly, it says ModSecurity doesn&#8217;t support content encodings. That is, it cannot inspect gzipped content. This is problematic especially when ModSecurity is running on reverse proxy. The question is, &#8220;how can I inspect, then?&#8221; There are some very useful advice from the developer in the list archive. Bad news is, <a href="http://article.gmane.org/gmane.comp.apache.mod-security.user/5044">it doesn&#8217;t work</a>. Some claims <a href="http://klaubert.wordpress.com/2009/06/17/modsecurity-vs-content-compression/">it worked</a>, but they skip deflate process by SetEnvIfNoCase, which is not an option for me.</p>

<p>My goal is:</p>

<ul>
<li>Compress by Content-Type, not by file extension because sometime file extension is not available (/foo.php?imageid=1234). You cannot use SetEnvIfNocase because it cannot access to response headers.</li>
<li>Do not compress images, video and other pre-compressed files (compress all except a few others).</li>
<li>Do not compress before ModSecurity inspect the content (the goal).</li>
</ul>

<p>After hours and days to find why it doesn&#8217;t work, I finally found the problem. In mod<em>ext</em>filter.c, it looks for ext filter by f->frec->name, which is not the name of ext filter but FilterProvider&#8217;s name when it should have looked for it by &#8220;nodeflate&#8221; in my case.</p>

<pre><code>583     /* look for the user-defined filter */
584     ctx-&gt;filter = find_filter_def(f-&gt;r-&gt;server, f-&gt;frec-&gt;name);
</code></pre>

<p>I&#8217;m not an apache guru in any way, I might be wrong.</p>

<p>Three tricks: </p>

<ul>
<li>Even though configtest doesn&#8217;t complain, ExtFilterDefine is only valid in server config context</li>
<li>DO NOT &#8220;SetOutputFilter DEFLATE&#8221;. It compresses all contents, ignoring nodeflate</li>
<li>Define two ext filters</li>
</ul>

<p>Here is the WORKING config.</p>

<pre><code>    LoadModule ext_filter_module libexec/apache22/mod_ext_filter.so
    LoadModule filter_module libexec/apache22/mod_filter.so
    ...
    # Netscape 4.x has some problems...
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    # Netscape 4.06-4.08 have some more problems
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    # IE is ok, but looked like Netscape, so we reset it
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

    # We need to force compression since we will remove the
    # request Content-Encoding/TE headers which mod_deflate
    # looks for.
    SetEnvIfNoCase Accept-Encoding gzip force-gzip
    SetEnvIfNoCase TE gzip force-gzip

    # Disable compression from backend
    RequestHeader unset Accept-Encoding
    RequestHeader unset TE

    # Make sure caching still works
    Header append Vary User-Agent env=!dont-vary

    # XXX be sure to define ExtFilterDefine in server config context!
    # not in virtual host, not directory, etc
    ExtFilterDefine nodeflate mode=output \
        cmd=/usr/bin/true \
        enableenv=SomeVarThatWillNeverBeSet
    # XXX workaround a bug in mod_ext_filter.
    # it looks up extfilter by FilterProvider's name, not user defined ext filter.
    # it complains "couldn't find definition of filter 'compress'"
    # Define the same name of FilterProvider.
    ExtFilterDefine compress mode=output \
        cmd=/usr/bin/true \
        enableenv=SomeVarThatWillNeverBeSet

    # Setup the filter to compress the response if we saw
    # an Accept-Encoding/TE header and marked it as force-gzip
    FilterDeclare compress CONTENT_SET
    FilterProvider compress DEFLATE env=force-gzip =1

    # Overwrite the "deflate" filter with the "nodeflate"
    # for various content types so they will not be compressed.
    # This is done as a hack because there is no way to
    # use more than one condition with FilterProvider above.
    FilterProvider compress nodeflate Content-Type $image/
    FilterProvider compress nodeflate Content-Type $application/
    FilterProvider compress nodeflate Content-Type $video/
    FilterProvider compress deflate Content-Type $application/javascript
    FilterProvider compress deflate Content-Type $application/json
    FilterProtocol compress "change=yes"

    FilterDeclare  modsec CONTENT_SET
    FilterProvider modsec modsecurity_out env=modsec-ignore !=1

    FilterChain modsec compress
</code></pre>

<p>I tested this on FreeBSD, so, use &#8220;cmd=/bin/true&#8221; on Linux and others (&#8220;/bin/sh&#8221; should work and is more portable, if you prefer).</p>

<p>When Apache 2.4 is released, it will be much simpler. See &#8220;<a href="http://bahumbug.wordpress.com/2008/03/31/expression-parser-for-apache/">Expression parser for Apache</a>&#8221;.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Batch image exporting from .fla</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2010/01/30/batch-image-exporting-from-fla.html" />
    <id>tag:journal.reallyenglish.com,2010://1.27</id>

    <published>2010-01-29T15:18:30Z</published>
    <updated>2011-06-01T10:41:02Z</updated>

    <summary> Just wanted to post a small .jsfl code snippet to export .png images from each frames in the current timeline (with the currenrt .png export settings). _ExportImages.jsflDownload Demo Files Although the same is possible by &quot;Export&quot; -&gt; &quot;Export Movie...&quot;...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="flash" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jsfl" label="jsfl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tools" label="tools" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<div class="lang-section en">
<p>
Just wanted to post a small .jsfl code snippet to export .png images from each frames in the current timeline (with the currenrt .png export settings).  
</p>

<p>
<a href="/2010/01/30/ExportImages/_ExportImages.jsfl">_ExportImages.jsfl</a><br /><a href="/2010/01/30/ExportImages/ExportImagesTest.zip">Download Demo Files</a>
</p>

<p>
Although the same is possible by "Export" -> "Export Movie..." then choosing "png sequence" as the file format, jsfl can be more flexible as; 
<ol>
<li><strike>It can export images from any (current) timeline</strike><br />Correction: It is also possible from "Export Movie", sorry for my ignorance.. orz</li>
<li>It can possibly perform more complex batch processing (with a bit of code modification)</li>
<li>The direct keyboard shortcut (with no dialog) can be assigned to it</li>
</ol>
</p>

<h4>Basic Usage</h4>
<ol>
<li>Open the .fla from which you want to export the image (In the Demo, it is "ExportImagesTest.fla").</li>
<li>From the menu, "Commands" -> "Run Command..." and open "_ExportImages.jsfl".</li>
</ol>

<p>
And, here is the Adobe Reference for how to run .jsfl in different ways;<br />
<a href="http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00003801.html">Running JSFL files (Adobe Livedocs)</a>
</p>

<p>
The image file names or location can be easily modified by editing the line with the comment. It saved me quite a lot of time so hopefully it could help be some help for any of you in any way.
</p>

<h4>Additional Note (1, June, 2011)</h4>
<p>
Added a simple example that exports .png files from multiple .fla files in a specified directory (tested on Flash CS4 / CS5.5 on Mac OSX 10.6)
</p>
<p>
<a href="/2010/01/30/ExportImages/_ExportImagesEX.jsfl">_ExportImagesEX.jsfl</a><br /><a href="/2010/01/30/ExportImages/ExportImagesEXTest.zip">Download Demo Files</a>
</p>
</div>

<div class="lang-section ja">
<p>
現在開いている.flaの各フレームから連番で.pngを書き出す超シンプルな.jsflスニペット、メモとして一応あげておきますね(Flash CS3とCS4で動作確認)。 
</p>

<p>
<a href="/2010/01/30/ExportImages/_ExportImages.jsfl">_ExportImages.jsfl</a><br /><a href="/2010/01/30/ExportImages/ExportImagesTest.zip">Download Demo Files</a>
</p>

<p>
実際"Export" -> "Export Movie"から.pngを連番で書き出せばいい話なのですが、<strike>jsflでならどのタイムラインからでも書き出せたり</strike>(Export Movieでもできました、知らなかったorz)、名前のコントロールが柔軟だったり、ダイアログなしで一発で終わるようにショートカットをあてがえたり、より複雑なバッチ処理にも使えたりするのがいいんじゃないかと思います。
</p>

<h4>使い方</h4>
<ol>
<li> イメージ書き出し元の.flaを開く(デモでは "ExportImagesTest.fla")。</li>
<li>"コマンド" -> "コマンドの実行"を選び、"_ExportImages.jsfl"を開く。</li>
</ol>

<p>
あとAdobeのリファレンスにいろんな方法でコマンド(.jsfl)を走らせる方法が書いてあります（一応です）<br  />
<a href="http://livedocs.adobe.com/flash/9.0_jp/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00003801.html">Running JSFL files (Adobe Livedocs)</a>
</p>

<p>
超簡単なわりにわりと重宝したのでもし良ければという感じです。(とはいえjsflはしくじるとこわいのでどうぞ前もってお試しの上使ってください。。）
</p>

<h4>追記 (1, June, 2011)</h4>
<p>
指定したディレクトリにある複数の.flaから.pngファイルをExportする.jsflのサンプルを追加しました (tested on Flash CS4 / CS5.5 on Mac OSX 10.6)
</p>
<p>
<a href="/2010/01/30/ExportImages/_ExportImagesEX.jsfl">_ExportImagesEX.jsfl</a><br /><a href="/2010/01/30/ExportImages/ExportImagesEXTest.zip">Download Demo Files</a>
</p>
</div>]]>
        
    </content>
</entry>

<entry>
    <title>Excluding certain matches in String.replace (JavaScript RegEx)</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2010/01/19/excluding-certain-matches-in-regex-javascript.html" />
    <id>tag:journal.reallyenglish.com,2010://1.25</id>

    <published>2010-01-18T18:35:34Z</published>
    <updated>2010-01-30T22:58:57Z</updated>

    <summary> The other day I wanted to emphasize all the numbers in HTML text dynamically with JavaScript for some reason. First it was quite simple enough even to my RegEx-dummy brain. I just wrote something like the following; (JavaScript) function...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="javascript" label="JavaScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="regex" label="RegEx" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>
The other day I wanted to emphasize all the numbers in HTML text dynamically with JavaScript for some reason. First it was quite simple enough even to my RegEx-dummy brain. I just wrote something like the following;
</p>

<p>
<div>(JavaScript)</div>
<pre><code>function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/(\d)/g, "&lt;em&gt;$1&lt;/em&gt;");
  return false;
}</code></pre>
</p>

<p>
<div>(HTML)</div>
<pre><code>&lt;p id="text"&gt;You have finished 3 lessons. Your score was 80/100. This is end of Stage 1. Please proceed to Stage 2. (By the way my number is 012-345-6789).&lt;/p&gt;</code></pre>
</p>

<p>
So far it was simple enough. However when I looked at <a href="/2010/01/31/RegExTest/test1.html">the consequence</a>, I noticed that we did not want to emphasize the numbers followed by the word &quot;Stage&quot;, as in &quot;1&quot; in &quot;Stage 1&quot; and &quot;2&quot; in &quot;Stage 2&quot;. And I did not know the way how to exclude only these from the RegEx matches to be replaced.
</p>

<p>
Without too much consideration, first I tried the following;
</p>

<p>
<pre><code>function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/[^(Stage )](\d)/g, "&lt;em&gt;$1&lt;/em&gt;");
  return false;
}</code></pre>
</p>

<p>
Here I tried to mean "match with any digits which are preceded by anything other than the string 'Stage ' (as well as trying to exclude the grouped characters 'Stage ' from back-references)".  However the result was <a href="/2010/01/31/RegExTest/test2.html">miserable</a>.  Honestly I still cannot even explain what exactly happened here.　Anyways, I understood that grouping with parenthesis ("()") in character class square bracket("[]") does not work (does it?). 
</p>

<p>
After a while of googling, I found that there is an RegEx expression called <a href="http://www.regular-expressions.info/lookaround.html">"negative lookbehind"</a>.  It took me about an hour to even vaguely understand the concept, but this seemed to be the answer.  So anyways, I tried the following just mimicking the tutorial page;
</p>

<p>
<pre><code>function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/[^(?&lt;!Stage )(\d)/g, "&lt;em&gt;$1&lt;/em&gt;");
  return false;
}</code></pre>
</p>

<p>
It <a href="/2010/01/31/RegExTest/test3.html">did not work at all</a> and ended up in a JavaScript error.  Soon after that, I found that I missed out one important line in the <a href="http://www.regular-expressions.info/lookaround.html">tutorial page</a>;
<blockquote cite="http://www.regular-expressions.info/lookaround.html">
Finally, flavors like JavaScript, Ruby and Tcl do not support lookbehind at all, even though they do support lookahead.
</blockquote>
OK great, (negative) lookbehind is NOT supported in current JavaScript (as of 2010 Jan, JavaScript 1.8.1) RegEx.
</p>

<p>
After all, I resolved the problem by doing the following.
</p>

<p>
<pre><code>function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/(?:Stage\s)?(\d)/g, function(str, p1){
    if(str.indexOf("Stage ")!=-1) return str;
    else return "&lt;em&gt;" + p1 + "&lt;/em&gt;";
  });
  return false;
}</code></pre>
</p>

<p>
This finally <a href="/2010/01/31/RegExTest/test4.html">worked</a>. I did not know that the String.replace method accepts a function instead of a replacing string as the second parameter.<br />
<a href=">https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/String/Replace">String.replace (MDC Core JavaScript 1.5 reference)</a> - <cite>Specifying a function as a parameter</cite><br />
</p>

<p>
However I'm not sure if this is the best solution - is there better and easier way to do the same?
</p>]]>
        
    </content>
</entry>

<entry>
    <title>Dynamic, redundant routing with OpenBSD</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/12/06/dynamic-redundant-routing-with-openbsd-1.html" />
    <id>tag:journal.reallyenglish.com,2009://1.24</id>

    <published>2009-12-06T10:56:31Z</published>
    <updated>2009-12-06T15:12:44Z</updated>

    <summary>Almost all serious project require redundancy, reallyenglish is no exception. carp(4), developed by OpenBSD project, is a free implementation of VRRP, which is patented by Cisco. carp(4) has load balancing based on L2 and L3, but here, I&apos;m going to...</summary>
    <author>
        <name>Tomoyuki Sakurai</name>
        
    </author>
    
        <category term="Networking" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="OpenBSD" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="ospf" label="ospf" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="routing" label="routing" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>Almost all serious project require redundancy, reallyenglish is no exception. <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=carp&amp;sektion=4" title="carp(4)">carp(4)</a>, developed by OpenBSD project, is a free implementation of VRRP, which is patented by Cisco. carp(4) has load balancing based on L2 and L3, but here, I'm going to focus on its fail over feature.</p>

<pre><code>            | 192.168.100.254/24
     .------+------.
 vr0 |         vr0 |
 .---+---. vr3 .---+---.
 | core1 +-----+ core2 |
 `---+---'     `---+---'
 vr1 |          vr1|
     `------+------'
            | 192.168.200.254/24
</code></pre>

<p>Firstly, enable IPv4 forwarding. Also, enable preemption to failover all carp interfaces altogether when one interface fails.</p>

<pre><code># sysctl net.inet.ip.forwarding=1
# echo net.inet.ip.forwarding=1 &gt;&gt; /etc/sysctl.conf
# sysctl net.inet.carp.preempt=1
# echo net.inet.carp.preempt=1 &gt;&gt; /etc/sysctl.conf
</code></pre>

<p>Using carp(4) is fairly simple. Here is what <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=hostname.if&amp;sektion=5" title="hostname.if(5)">hostname.if(5)</a> looks like.</p>

<pre><code>/etc/hostname.vr0:     up
/etc/hostname.vr1:     up
/etc/hostname.vr3:     inet 172.16.0.1/30
/etc/hostname.carp0:   192.168.100.254 vhid 1 carpdev vr0 pass mypass
/etc/hostname.carp1:   192.168.200.254 vhid 2 carpdev vr1 pass mypass
/etc/hostname.pfsync0: syncdev vr3
</code></pre>

<p>Bring up the interfaces. You can also use <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=ifconfig&amp;sektion=8" title="ifconfig(8)">ifconfig(8)</a>, but I always prefer
startup script to make sure that the configuration will not be lost.</p>

<pre><code># sh /etc/netstart vr0
# sh /etc/netstart vr1
# sh /etc/netstart vr3
# sh /etc/netstart carp0
# sh /etc/netstart carp1
# sh /etc/netstart pfync0
</code></pre>

<p>If you insists on using ifconfig(8):</p>

<pre><code># ifconfig vr0 up
# ifconfig vr1 up
# ifconfig vr3 inet 172.16.0.1/30
# ifconfig carp0 create
# ifconfig carp1 create
# ifconfig carp0 192.168.100.254 vhid 1 carpdev vr0 pass mypass
# ifconfig carp1 192.168.200.254 vhid 2 carpdev vr0 pass mypass
# ifconfig pfsync0 syncdev vr3
</code></pre>

<p>Repeat almost same configuration on core2. The difference is each carp interface has advskew keyword and vr3 for pfsync device has different IP address. A router with higher advskew value becomes slave.</p>

<pre><code>/etc/hostname.vr3:     inet 172.16.0.2/30
/etc/hostname.carp0: 192.168.100.254 vhid 1 carpdev vr0 pass mypass advskew 100
/etc/hostname.carp1: 192.168.200.254 vhid 2 carpdev vr1 pass mypass advskew 100
</code></pre>

<p>Now you have redundant firewalls. Easy!</p>

<p>As explained in <a href="http://journal.reallyenglish.com/2009/11/20/ospf-over-gre-over-ipsec-with-openbsd.html" title="OSPF over GRE over IPSec with OpenBSD">the earlier entry</a>, we use OSPF for internal routing. How do I establish OSPF neighbor? Because <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=ospfd&amp;sektion=8" title="ospfd(8)">ospfd(8)</a> cannot be enabled actively on carp'ed interface, you need real interface that connects OSPF cloud and core routers.  Additionally, real interface cannot preempt carp interface. That means when the real interface fails, you cannot failover. To workaround this problem, you need two OSPF-enabled routers and two links on each core. Things get messy from now on.</p>

<pre><code>                                     carp0
           udav1   vr1    sis0      /
-----.      .------.     .-------. / 
     +------+  r1  +-----+ core1 |&lt;
     |      `------'     `-------' \
     |     udav0|vr2\   / sis1  \   \
     |          |    \ /         \   carp1
OSPF |          |     X        pfsync0
     |          |    / \         /   carp0
     |     udav0|vr1/   \ sis0  /   /
     |      .------.     .-------. / 
     +------|  r2  +-----+ core2 |&lt;
-----'      `------'     `-------' \
           udav1   vr2     sis1     \
                                     carp1
</code></pre>

<p>In this setup, when one of the link from core to OSPF cloud fails, traffic will be routed via the link between r1 and r2. When carp'ed interface fails, preemption kicks in and ospfd(8) on core1 will remove the routes and r1 will not route traffic to core1.  claudio@, one of "the networking guy" in OpenBSD <a href="http://www.mail-archive.com/misc@openbsd.org/msg41709.html" title="Re: CARP, carpdemote and kernel routing table">admitted</a> it's not optimal. Hopefully, it will be fixed in the future release.</p>

<p><a href="http://www.pcengines.ch/alix2d3.htm" title="ALIX 2D3">ALIX 2D3</a> board, which is used as r1 and r2, has only three ports. And one port is used for diskless boot in this testing. So, i added two USB ethernet adopters, deteced as <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=udav&amp;sektion=4" title="udav(4)">udav(4)</a>. Make sure the right patch goes to the right port. Each link between the routers has a /30 subnet. If confused, draw a diagram on paper.</p>

<p>Let's enable OSPF on all interface on every router, but not on real interfaces used for carp. <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=ospfd.conf&amp;sektion=5" title="ospfd.conf(5)">ospfd.conf(5)</a> looks like:</p>

<pre><code># core1 and core2
auth-type crypt
auth-md 1 "mypass"
auth-md-keyid 1

area 0.0.0.0 {
  # link to r1/r2
  interface sis0 { metric 10 }
  interface sis1 { metric 20 }
  # you can omit "passive" on carp interface. it's always passive anyway
  interface carp1 { passive }
  interface carp0 { passive }
}

# r1 and r2
auth-type crypt
auth-md 1 "mypass"
auth-md-keyid 1

area 0.0.0.0 {
  # link to core
  interface vr1 { metric 10 }
  interface vr2 { metric 20 }
  interface udav0 { }
  interface udav1 { }
}
</code></pre>

<p>Run ospfd(8) on every router. The output of ospfctl(8) on core1 looks like this.</p>

<pre><code># ospfctl sh int
Interface   Address            State  HelloTimer Linkstate  Uptime    nc  ac
carp0       192.168.100.254/24 DOWN   -          master     00:00:00   0   0
carp1       192.168.200.254/24 DOWN   -          master     00:00:00   0   0
sis1        192.168.0.5/30     BCKUP  00:00:00   active     1d06h19m   1   1
sis0        192.168.0.1/30     BCKUP  00:00:00   active     1d06h19m   1   1

# ospfctl sh ne
ID              Pri State        DeadTime Address         Iface     Uptime
172.16.254.202  10  FULL/DR      00:00:33 192.168.0.6     sis1      1d06h20m
172.16.254.201  1   FULL/DR      00:00:32 192.168.0.2     sis0      1d06h20m
</code></pre>

<p>Now the fun (and boring) part. While pinging from a host in OSPF cloud to the other end of core, pull out the cable randomly. You can shutdown one of the router, too. Nothing should happen, other than normal ping output. If it doesn't work, <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=tcpdump&amp;sektion=8" title="tcpdump(8)">tcpdump(8)</a> is your friend. You can manually fail over the master by:</p>

<pre><code># ifconfig -g carp carpdemote 10
</code></pre>

<p>This setup requires no additional package and works out of the box. If you need more redundancy, i.e. redundancy at application level, than this setup, OpenBSD also provides <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=relayd&amp;sektion=8" title="relayd(8)">relayd(8)</a>. If you need redundant DHCP servers, modified version of <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=dhcpd&amp;sektion=8" title="dhcpd(8)">dhcpd(8)</a> has synchronization support. OpenBSD makes redundant networking fairly easy.</p>

<p>Happy redundancy!</p>
]]>
        

    </content>
</entry>

<entry>
    <title>FreeBSD/Jailを使用したプログラマのための仮想環境 - ２</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/11/29/freebsd-jail-for-programmer-2.html" />
    <id>tag:journal.reallyenglish.com,2009://1.16</id>

    <published>2009-11-29T10:55:50Z</published>
    <updated>2009-11-29T21:40:50Z</updated>

    <summary>前回に引き続き、今回はFreeBSDのJailの簡単な説明と、実際にどのような感じで使えるのか、簡単なサンプルを交え紹介します。 「プログラマのための」について 前回書き忘れてしまったのですが、なぜ「プログラマのための」というのをタイトルに入れたかというと、 プログラマは自分の開発環境／テスト環境の構築ぐらい自分ですべし でも、環境構築に時間をかけすぎるのはプログラマとしては本末転倒だよね この二つをあっさりと解決してくれるのがFreeBSDのJailだと感じているからです。 それと、自分自身そこそこ長いことプログラマをやってますが、Jailは自分にとってなかなか衝撃的だった、というのもこのエントリを書くきっかけになっているというのもあります。 FreeBSDのJailとは さて、まず基本的なFreeBSDのJailについて簡単に触れておきます。 FreeBSDのJailは仮想環境の一つの実装です。仮想環境にも色々ありますがJailはその中でもとてもシンプルな物です。一つの物理的なサーバ上で動いている一つのFreeBSD（以下Jailホスト）の上で、複数のFreeBSD（以下Jailゲスト）が動いているように見えるようにする仕組です。「見えるようにする」だけというのがポイントで、実際にはJailホスト上のカーネルの上ですべてのプロセスが動いているだけです。 また、Jailとchrootを同じようなもの、と考えている人もいるようですが、chrootがファイルシステムだけが対象なのに対し、Jailはファイルシステムに加えネットワークやプロセスといったものも管理下になるのが違います。Jailゲスト一つが独立したIP addressを持ちます。 外からネットワーク越しに見ると、Jailゲストは一つのFreeBSD OSのように見えます。しかし、実際には、Jailホスト上の１つのカーネルで、Jailゲスト上のすべてのプロセスが動いています。このことは、Jailホスト上のカーネルからJailゲスト上の各プロセスを普通にpsやtopコマンド等で確認することができます。 また、この仕組みがそのままいくつかのJail自体の制限になります。たとえば、違うバージョンのFreeBSDや、違うOSを仮想環境として入れるといったVMWareやXenといった他の仮想環境でできることができません。そして、（今のところ）各Jailゲストで動くプロセスに対してリソースの割当や制限をすることができません。ですので一つのJailゲストがリソースを食い過ぎてしまうと他のJailゲストに大きく影響を与えます。この辺は将来的には何かできるようになるかも、という話です。 実際に動いている環境での例を示します。 これは、実際に弊社で稼働中のJailホストでtopした結果です。&#8221;j&#8221;を押すと左から２列目にJID (Jail ID)というものが表示されます。これはそのプロセスがどのJailゲストで動いているかということを示します。このようにJailホストからは、Jailゲストのプロセスが普通に見ることができますし、またJailホスト上からJailゲストのプロセスのkillなどは普通にできます。 では、その中の一つのJailゲストに入り、同じようにtopコマンドを実行してみます。すると、以下のようにそのJailゲストのプロセスのみが表示されます。 このJailゲストはPostgreSQL用のものなのでPostgreSQLに関連するプロセスとcronなどの基本的なプロセスだけが走っているのがわかります。Jailゲストの中からは、他のJailゲストやJailホストの情報は見えません。これはプロセスだけではなくてファイルシステムなどもそうです。 とてもシンプルです。そして、シンプルなだけにに仮想環境を動かすこと自体のオーバヘッドが少なく、無駄なく一台のハードウェアの資源を使うことができます。また9年前にリリースされたFreeBSD 4.0Rからの機能なので安定度も非常に高いです。 資源という面では、Jailゲスト同士でFreeBSDのユーザランド部分をファイルレベルで共有するのでディスクスペースもそれほど無駄になりません。どう作るかにもよりますが、大雑把に言うと、/etc, /usr/local, /var あたりはJailゲスト毎ですが、/usr 以下は共有されます。また、もちろんパッケージからインストールしたものはJail毎になります。これにより資源を節約できるだけなく、Jailゲストの数をたくさん増やしたとしてもFreeBSDとしてのベース部分のメンテナンスは１カ所で済むのも楽なところです。 また、Jailゲストで使うファイルもJailホストと同じファイルシステム上にあるので、簡単に直感的に扱うことができます。例えば、あるJailゲスト上で「/etc/pam.d/systemを壊してしまって、仮想環境に入れなくなってしまった」というトラブルが起きたとします。Jailホスト上から見ると、このファイルは、/foo/bar/jails/hogehoge.example.com/etc/pam.d/system にあります。Jailホストにとっても普通のファイルなのでお使いのエディタで簡単に修復できます。 Jailの導入 Jail自体はFreeBSDに標準で組み込まれているのですが、その他にいくつか設定が必要です。また、Jail単体だと管理が大変なので、packageまたはportsから管理ツールであるsysutils/ezjailも導入してください。 さて、普通ならここでJailシステムのインストールの仕方等を紹介するべきなのかもしれませんが、ちょっと大変だし、世の中にあるものより劣化したドキュメントを垂れ流すだけになりそうなので、どこか適当な情報を探してください。 また、Jail自体についてはこの辺が詳しいです。 FreeBSD Handbook FreeBSD Wiki Wikipedia Jailを使用した運用例...</summary>
    <author>
        <name>Masatomo Nakano</name>
        <uri>http://twitter.com/masatomon</uri>
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="environment" label="Environment" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="freebsd" label="FreeBSD" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jail" label="Jail" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p><a href="/2009/10/21/freebsd-jail-for-programmer-1.html">前回</a>に引き続き、今回はFreeBSDのJailの簡単な説明と、実際にどのような感じで使えるのか、簡単なサンプルを交え紹介します。</p>

<h2>「プログラマのための」について</h2>

<p>前回書き忘れてしまったのですが、なぜ「プログラマのための」というのをタイトルに入れたかというと、</p>

<ul>
<li>プログラマは自分の開発環境／テスト環境の構築ぐらい自分ですべし</li>
<li>でも、環境構築に時間をかけすぎるのはプログラマとしては本末転倒だよね</li>
</ul>

<p>この二つをあっさりと解決してくれるのがFreeBSDのJailだと感じているからです。</p>

<p>それと、自分自身そこそこ長いことプログラマをやってますが、Jailは自分にとってなかなか衝撃的だった、というのもこのエントリを書くきっかけになっているというのもあります。</p>

<h2>FreeBSDのJailとは</h2>

<p>さて、まず基本的なFreeBSDのJailについて簡単に触れておきます。</p>

<p>FreeBSDのJailは仮想環境の一つの実装です。仮想環境にも色々ありますがJailはその中でもとてもシンプルな物です。一つの物理的なサーバ上で動いている一つのFreeBSD（以下Jailホスト）の上で、複数のFreeBSD（以下Jailゲスト）が動いているように見えるようにする仕組です。「見えるようにする」だけというのがポイントで、実際にはJailホスト上のカーネルの上ですべてのプロセスが動いているだけです。</p>

<p>また、Jailとchrootを同じようなもの、と考えている人もいるようですが、chrootがファイルシステムだけが対象なのに対し、Jailはファイルシステムに加えネットワークやプロセスといったものも管理下になるのが違います。Jailゲスト一つが独立したIP addressを持ちます。</p>

<p>外からネットワーク越しに見ると、Jailゲストは一つのFreeBSD OSのように見えます。しかし、実際には、Jailホスト上の１つのカーネルで、Jailゲスト上のすべてのプロセスが動いています。このことは、Jailホスト上のカーネルからJailゲスト上の各プロセスを普通にpsやtopコマンド等で確認することができます。</p>

<p>また、この仕組みがそのままいくつかのJail自体の制限になります。たとえば、違うバージョンのFreeBSDや、違うOSを仮想環境として入れるといったVMWareやXenといった他の仮想環境でできることができません。そして、（今のところ）各Jailゲストで動くプロセスに対してリソースの割当や制限をすることができません。ですので一つのJailゲストがリソースを食い過ぎてしまうと他のJailゲストに大きく影響を与えます。この辺は将来的には何かできるようになるかも、という話です。</p>

<p>実際に動いている環境での例を示します。</p>

<p><img src="/2009/11/28/jail-host-top.png" alt="host-top" title="" /></p>

<p>これは、実際に弊社で稼働中のJailホストでtopした結果です。&#8221;j&#8221;を押すと左から２列目にJID (Jail ID)というものが表示されます。これはそのプロセスがどのJailゲストで動いているかということを示します。このようにJailホストからは、Jailゲストのプロセスが普通に見ることができますし、またJailホスト上からJailゲストのプロセスのkillなどは普通にできます。</p>

<p>では、その中の一つのJailゲストに入り、同じようにtopコマンドを実行してみます。すると、以下のようにそのJailゲストのプロセスのみが表示されます。</p>

<p><img src="/2009/11/28/jail-guest-top.png" alt="guest-top" title="" /></p>

<p>このJailゲストはPostgreSQL用のものなのでPostgreSQLに関連するプロセスとcronなどの基本的なプロセスだけが走っているのがわかります。Jailゲストの中からは、他のJailゲストやJailホストの情報は見えません。これはプロセスだけではなくてファイルシステムなどもそうです。</p>

<p>とてもシンプルです。そして、シンプルなだけにに仮想環境を動かすこと自体のオーバヘッドが少なく、無駄なく一台のハードウェアの資源を使うことができます。また9年前にリリースされたFreeBSD 4.0Rからの機能なので安定度も非常に高いです。</p>

<p>資源という面では、Jailゲスト同士でFreeBSDのユーザランド部分をファイルレベルで共有するのでディスクスペースもそれほど無駄になりません。どう作るかにもよりますが、大雑把に言うと、/etc, /usr/local, /var あたりはJailゲスト毎ですが、/usr 以下は共有されます。また、もちろんパッケージからインストールしたものはJail毎になります。これにより資源を節約できるだけなく、Jailゲストの数をたくさん増やしたとしてもFreeBSDとしてのベース部分のメンテナンスは１カ所で済むのも楽なところです。</p>

<p>また、Jailゲストで使うファイルもJailホストと同じファイルシステム上にあるので、簡単に直感的に扱うことができます。例えば、あるJailゲスト上で「/etc/pam.d/systemを壊してしまって、仮想環境に入れなくなってしまった」というトラブルが起きたとします。Jailホスト上から見ると、このファイルは、/foo/bar/jails/hogehoge.example.com/etc/pam.d/system にあります。Jailホストにとっても普通のファイルなのでお使いのエディタで簡単に修復できます。</p>

<h2>Jailの導入</h2>

<p>Jail自体はFreeBSDに標準で組み込まれているのですが、その他にいくつか設定が必要です。また、Jail単体だと管理が大変なので、packageまたはportsから管理ツールであるsysutils/ezjailも導入してください。</p>

<p>さて、普通ならここでJailシステムのインストールの仕方等を紹介するべきなのかもしれませんが、ちょっと大変だし、世の中にあるものより劣化したドキュメントを垂れ流すだけになりそうなので、<a href="http://www.google.com/search?q=ezjail-admin">どこか適当な情報を探してください</a>。</p>

<p>また、Jail自体についてはこの辺が詳しいです。</p>

<ul>
<li><a href="http://www.freebsd.org/doc/en/books/handbook/jails.html">FreeBSD Handbook</a></li>
<li><a href="http://wiki.freebsd.org/Jails">FreeBSD Wiki</a></li>
<li><a href="http://en.wikipedia.org/wiki/FreeBSD_jail">Wikipedia</a></li>
</ul>

<h2>Jailを使用した運用例</h2>

<p>以下の例ではJailの管理ツールであるezjailを使っています。私はezjailができる前のJail事情を知らないのですが、その時代は色々と大変だったみたいです。</p>

<h3>例１: Jailの新規作成</h3>

<p>Jailゲストを新しく作ります。JailゲストはFQDNをディレクトリ名として作成され、その下がそのJailゲストの/(root)ディレクトリになります。</p>

<pre><code>$ sudo ezjail-admin create newjail.example.com 192.168.4.25
/usr/local/jails/newjail.example.com/./bin/usr/local/jails/newjail.example.com/./boot
/usr/local/jails/newjail.example.com/./dev
/usr/local/jails/newjail.example.com/./etc
/usr/local/jails/newjail.example.com/./etc/X11
/usr/local/jails/newjail.example.com/./etc/bluetooth
/usr/local/jails/newjail.example.com/./etc/bluetooth/hcsecd.conf
/usr/local/jails/newjail.example.com/./etc/bluetooth/hosts
/usr/local/jails/newjail.example.com/./etc/bluetooth/protocols
/usr/local/jails/newjail.example.com/./etc/defaults
（中略）
/usr/local/jails/newjail.example.com/./.cshrc
/usr/local/jails/newjail.example.com/./COPYRIGHT
/usr/local/jails/newjail.example.com/./basejail
</code></pre>

<p>この例では、192.168.4.25 というIP addressがこのJailゲストに設定されます。（Jailホスト側にも192.168.4.25というIP addressをaliasとしてふる必要もあります。）</p>

<p>作成したJailゲストを起動してみます。</p>

<pre><code>$ sudo ezjail-admin start newjail.example.com
Configuring jails:.
Starting jails: newjail.example.com.
</code></pre>

<p>Consoleに入ります。</p>

<pre><code>$ sudo ezjail-admin console newjail.example.com
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
     The Regents of the University of California. All rights reserved.

FreeBSD 7.2-STABLE (GENERIC) #0: Fri Aug  7 20:52:37 BST 2009

Welcome to FreeBSD!
（中略）
You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

newjail#
</code></pre>

<p>ここれでJailゲストが一つ作成され起動しました。newjail# のプロンプトが表示され、この以下の操作はJailゲストの仮想環境内の操作になります。この中からは他のJailゲストやJailホストの情報は全く見えません。この先は普通のFreeBSDと同じように好きなようにパッケージを入れたり設定したりできます。もちろんsshdを起動すれば外から直接newjailに入ってこれます。</p>

<p>このようにコマンド２、３個、所要時間１分未満で簡単に１つの仮想環境を作成することができます。</p>

<h3>例２: Jailゲストのコピー</h3>

<p>似たような環境を作るときにいちいち０から設定するのは大変です。こういうときは既にあるJailを簡単にコピーできます。</p>

<p>先ほど作成したnewjailをコピーし、newjail2を作成してみましょう。</p>

<p>いったんnewjailを停止。</p>

<pre><code>$ sudo ezjail-admin stop newjail.example.com
</code></pre>

<p>コピー</p>

<pre><code>$ sudo cp -a /usr/local/jails/newjail.example.com /usr/local/jails/newjail2.example.com
</code></pre>

<p>単純なファイルコピーなので、rsyncでもtarでもお好きなものでどうぞ。（パーミッションとかに気をつけて）</p>

<p>コピーしたファイルを元にnewjail2を作成します。(すでにあるファイルを使う場合は-xをつける）</p>

<pre><code>$ sudo ezjail-admin create -x newjail2.example.com 192.168.4.26
</code></pre>

<p>これで、完了です。</p>

<p>先ほどと同じようにコンソールに入りコピーされていることを確認します。(起動していない場合にはconsoleコマンドでstartもします。）</p>

<pre><code>$ sudo ezjail-admin console newjail2.example.com
Configuring jails:.
Starting jails: cms3-build.uk.reallyenglish.com.
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
     The Regents of the University of California. All rights reserved.

FreeBSD 7.2-STABLE (GENERIC) #0: Fri Aug  7 20:52:37 BST 2009

Welcome to FreeBSD!
（中略）
You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

newjail2#
</code></pre>

<p>これでコピーされたJailゲストが動きだしました。</p>

<p>ファイルのコピーにかかる時間は、もちろんその中のファイルの量によるので何とも言えませんが、実作業時間はこちらも数分といったところでしょう。</p>

<p>同じようなやり方で複数のJailホスト間でJailゲストをコピー（または、元のを消せば移動）することもできます。この場合コピー先のJailホストは同一のアーキテクチャのサーバ、同一のFreeBSDのバージョンのものにしておいた方が無難です。</p>

<h2>今回のまとめ</h2>

<p>とにかくJailは簡単です。よほど深いことをするのでない限りJail自体の知識はあまり必要となりません。普通のUNIX的な知識とFreeBSD的な知識があれば普段使いとしては十分です。</p>

<p>個人的な経験では、他の仮想環境はメンテナンス含め色々と手間がかかります。気づいたら動くなくなってた仮想環境というのも目にします。またメモリやディスクスペースのオーバヘッドも大きいので簡単にいくつも作ったりもできません。Jailはそういう意味でもとても軽いし堅いです。もし何らかの理由で動かなくなったとしても、上記で説明したようにとてもシンプルなのでわりと簡単に修復できますし、仮想環境の中のファイルを外から取り出すのも簡単です。</p>

<p>次回はもう少しだけ運用のTipsなどを紹介して最後にしたいと思っています。</p>

<p>それでは！</p>
]]>
        

    </content>
</entry>

<entry>
    <title>OSPF over GRE over IPSec with OpenBSD</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/11/20/ospf-over-gre-over-ipsec-with-openbsd.html" />
    <id>tag:journal.reallyenglish.com,2009://1.21</id>

    <published>2009-11-20T00:14:23Z</published>
    <updated>2009-11-25T07:14:30Z</updated>

    <summary>reallyenglish.com is geographically diverse. The HQ in UK, a few branches in Asia, maybe more in the future. Except for few exceptions, the employees expect universal services, such as source code repository, project management system and wiki. All of them...</summary>
    <author>
        <name>Tomoyuki Sakurai</name>
        
    </author>
    
        <category term="Networking" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="OpenBSD" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[reallyenglish.com is <a href="http://www.reallyenglish.com/company/locations/index.html">geographically diverse</a>. The HQ in UK, a few branches in Asia, maybe more in the future. Except for few exceptions, the employees expect universal services, such as source code repository, project management system and wiki. All of them must be protected by strong encryption. IPsec is a standard protocol designed for encrypting packets from one place to another. We extensively use IPsec between our offices.<br /><br />As a sysadmin, whenever someone says "the Internet is down", I say "no, it isn't". The problem would be caused by networking issue, misconfiguration by someone, maybe his own fault or whatever. The Internet is fine. But, partially, he is right. The Internet is the network of networks. Different network is managed by different entity. As such, links between networks<br />cut off for various reason every day somewhere on the Internet. You just don't know it is happening. The Internet as a whole works somehow thanks to "dynamic routing".<br /><br />What dynamic routing does is, in short, "if there are multiple paths to the destination, use the best path" and "tell neighbors about your directly connected networks so that others can understand the whole network map". Without dynamic routing, you have to teach every possible route to every single router. For our intranet, we're using OSPF.<br /><br />Okay, for robust intranetworking, all you need is multiple meshed IPsec tunnels with OSPF. IPSec is a standard and mature protocol, and so is OSPF. Sounds easy? Not quite. What I don't really like about IPsec is, it wasn't designed with routing in mind. As Security Association is statically configured, you cannot specify multiple path to a destination. Moreover, it doesn't handle multicast packet. OSPF is a routing protocol and uses multicast for its communication.<br /><br />One more thing to make this problem complicated is proprietary products, Netscreen security devices to be specific, we're still using. If you stick with a specific vendor, you will not have interoperability problem, but you're successfully vendor locked-in. What you can do is what that particular vendor implemented. If they don't, you cannot do anything with it. Anyway, I strongly prefer open standards and open platforms. The choice in this case is <a href="http://www.openbsd.org/">OpenBSD</a>. However, there wasn't documentation about how to implement meshed, dynamically routed IPsec with OpenBSD and ScreenOS.<br /><br />IPsec doesn't like multicast pakcet. Okay, use GRE, Generic Routing Encapsulation. By encapsulating multicast packet into GRE unicast packet, IPsec happily forward the packet to its peer. When the link to the peer goes down, <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=ospfd&amp;sektion=8">ospfd(8)</a> marks the link as unavailable and use alternative path to the destination. Sounds simple, isn't it? Again, not quite. You have to understand all the network layers involved. There would be 6 endpoints, or IP addresses, involved in this setup. IPsec endpoints, GRE tunnel endpoints and a /30 network for OSPF communication.<br /><br />Let's configure OpenBSD first. Make sure both packet forwarding and GRE are enabled. Also, you better to disable <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=pf&amp;sektion=4">pf(4)</a> during the testing. You can enable it again after everything works. OpenBSD 4.6 and later enable <a href="http://www.openbsd.org/faq/pf/">pf</a> by default.<br /><br />
<pre># sysctl net.inet.gre.allow=1
# sysctl net.inet.ip.forwarding=1
# pfctl -d
</pre><br />Next, create GRE tunnel.<br /><br />
<pre># ifconfig gre0 create
# ifconfig gre0 tunnel myglobal.ip.addre.ss peerglobal.ip.addre.ss (outer header)
# ifconfig gre0 inet mygre.ip.addre.ss peergre.ip.addre.ss netmask 0xffffffff link0 up (inner header)
</pre><br />The packets between mygre.ip.addre.ss and peergre.ip.addre.ss will be encapsulated by GRE unicast packets with the global IP addresses of the both endpoints as source and destination header. GRE packets are not encrypted, yet.<br /><br />Then, configure IPsec. OpenBSD's newer <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=ipsec.conf&amp;sektion=5">ipsec.conf(5)</a> makes IPsec configuration much easier than ever. The security policy would be "encrypt all packets between the endpoints with their global address". Due to performance limitation of the hardware, we use SHA1 and 3DES.<br /><br />
<pre># vi /etc/ipsec.conf
mypeer = "peerglobal.ip.addre.ss"
me = "myglobal.ip.addre.ss"
mypassword = "password"<br /> 
ike esp from $me to $mypeer peer $mypeer \
 main auth hmac-sha1 enc 3des group modp1024 \
 srcid $me/32 dstid $mypeer/32 \
 psk $mypassword</pre><br />Start isakmpd and tell it to read security policy from /etc/ipsec.conf.<br /><br />
<pre># isakmpd -K
# ipsecctl -f /etc/ipsec.conf
</pre><br /><br />NS 5GT's config is not so straight forward, but almost same you did above on OpenBSD.<br /><br /><pre>set interface tunnel.1 zone untrust
set interface tunnel.1 ip mygre.ip.addre.ss/30 (inner header)
set interface tunnel.1 tunnel encap gre
set interface tunnel.1 tunnel local-if untrust dst-ip global.ip.addre.ss (outer GRE header, GRE endpoints)
set interface tunnel.1 tunnel keep-alive (optional, but useful to see GRE packet on the wire)
set ike gateway mypeer address peerglobal.ip.addre.ss main outgoing-interface "untrust" preshare password sec-level compatible
set vpn mypeer gateway jp proposal "nopfs-esp-3des-sha" 
set vpn mypeer bind interface tunnel.1
set vpn mypeer proxy-id local-ip global.ip.addre.ss/32 remote-ip peerglobal.ip.adre.ss/32 ANY</pre><br /><div>The gotcha was, I thought it wasn't possible for OpenBSD and 5GT to talk to each other in a setup like this because OpenBSD's GRE tunnel is point-to-point, 5GT's is a normal /30 subnet. I even didn't give it a try during the initial testing. In fact, it is. Now, you can ping the peer using GRE /30 IP address each other. <br /></div><br /><br /><pre># ping peergre.ip.addre.ss<br />PING peergre.ip.addre.ss (peergre.ip.addre.ss): 56 data bytes<br />64 bytes from peergre.ip.addre.ss: icmp_seq=0 ttl=64 time=277.665 ms<br />...</pre><br /><br />You'll see ICMP packets on the GRE interface.<br />
<pre># tcpdump -tnei gre0 -c 10 icmp 
tcpdump: listening on gre0, link-type NULL
mygre.ip.addre.ss &gt; peergre.ip.addre.ss: icmp: echo reply
peergre.ip.addre.ss &gt; mygre.ip.addre.ss: icmp: echo request
...
</pre><br /><br />Make sure the traffic is encrypted. Replace vr0 with your egress interface's name.<br /><pre># ipsecctl -s all
FLOWS:
flow esp in from myglobal.ip.addre.ss to peerglobal.ip.addre.ss peer peerglobal.ip.addre.ss srcid myglobal.ip.addre.ss/32 dstid peerglobal.ip.addre.ss/32 type use
flow esp out from peerglobal.ip.addre.ss to myglobal.ip.addre.ss peer peerglobal.ip.addre.ss srcid peerglobal.ip.addre.ss/32 dstid myglobal.ip.addre.ss/32 type require

SAD:
esp tunnel from myglobal.ip.addre.ss to peerglobal.ip.addre.ss spi 0x1275cf8c auth hmac-sha1 enc aes
esp tunnel from peerglobal.ip.addre.ss to myglobal.ip.addre.ss spi 0x20eec763 auth hmac-sha1 enc aes

# tcpdump -tni vr0 -c 10
tcpdump: listening on vr0, link-type EN10MB
esp myglobal.ip.addre.ss &gt; peerglobal.ip.addre.ss spi 0x61a862f2 seq 45586 len 372
esp peerglobal.ip.addre.ss &gt; myglobal.ip.addre.ss spi 0x84cd621d seq 45973 len 132
</pre>
Now that both IPsec and GRE tunnel worked, the last thing you need is enabling OSPF. ospfd.conf is very simple. Replace vr1 with your internal network interface.<br /><br /><pre># vi /etc/ospfd.conf
password="mypassword"
auth-md 1 $password
auth-type crypt
auth-md-keyid 1
area 0.0.0.0 {
 interface gre0 { }
 interface vr1 { passive }
}
</pre>
<br />Start ospfd(8) in debug and verbose mode.<br /><br /><pre># ospfd -dv
... lots of debug information ...
</pre><br />
Do the same thing on 5GT.
<br /><br /><pre>set vr trust-vr protocol ospf enable
set interface tunnel.1 protocol ospf area 0.0.0.0
set interface tunnel.1 protocol ospf authentication md5 mypassword key-id 1
set interface tunnel.1 protocol ospf authentication active-md5-key-id 1
set interface tunnel.1 protocol ospf enable
set interface trust protocol ospf area 0.0.0.0
set interface trust protocol ospf passive
set interface trust protocol ospf enable
</pre><br />Now you'll see OSPF neighbor relationship is established.<br /><br />
<pre># ospfctl show neighbor
ID                      Pri State      DeadTime Address                Iface     Uptime
peergre.ip.addre.ss     1   FULL/P2P   00:00:30 peergre.ip.addre.ss    vr1       00:00:23
</pre> 
<br />run "ospfctl show rib" to see RIB and "ospfctl show fib" to see FIB. It should show you the network at the peer's end. If it doesn't work for you, make sure IPsec flow is established,&nbsp; OSPF packet is flowing between both hosts. To make a meshed IPsec, simply repeat this procedure. Tedious? Well, for that matter, you have to replace all the proprietary boxes with OpenBSD and use some kind of automated configuration management system.]]>
        
    </content>
</entry>

<entry>
    <title>How I made my Flash dead silent</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/11/20/an-unusual-trap.html" />
    <id>tag:journal.reallyenglish.com,2009://1.20</id>

    <published>2009-11-19T20:42:48Z</published>
    <updated>2009-12-21T00:01:11Z</updated>

    <summary> どうでも良い失敗談なのですが、先日.flaからswfをPublishしてもActionScriptが全く認識されずtraceもエラーも出力されず、本当にうんともすんともいわないという状態に陥りました。（Publishは成功するがActionScriptが全く認識されないという状態） 本当にうんともすんとも言わないので原因の手がかりが掴めず、classpath、document classのリンケージのチェック、ASO削除、TextMateでASファイルにBOMを加えてみるなどいろいろ試したんですが全然駄目で、数時間を無駄にしようとしていたそのとき、自分のミスに気がつきました。 画像のように、どうやら何かの拍子で誤ってLibraryのMovieClip Symbolのひとつに、(Base Classにではなく直接)flash.display.Spriteをリンケージしてしまっていたようです。 何故自分でもこんなことをやってしまったのかわかりませんが、これをやってしまうと上記のようにCS4(Mac版)だとpublishはするものの出力が完全沈黙するので、下手をするとはまります（因みにCS３で試したところIDEがクラッシュしました）。たぶんこんなアホなことをやるのは自分だけだろうと思いつつも、もし同じ症状に出くわしたら、一応各Symbolのリンケージをチェックしてみてください。。 This is one of my trivial horror stories - the other day I made changes on some Flash stuff I was working on and published the .fla as usual. However, it suddenly...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
    <category term="actionscript" label="ActionScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flash" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[ <div class="lang-section ja">
<p>
どうでも良い失敗談なのですが、先日.flaからswfをPublishしてもActionScriptが全く認識されずtraceもエラーも出力されず、本当にうんともすんともいわないという状態に陥りました。（Publishは成功するがActionScriptが全く認識されないという状態）
</p>
<p>
本当にうんともすんとも言わないので原因の手がかりが掴めず、classpath、document classのリンケージのチェック、ASO削除、<a href="http://episteme.arstechnica.com/eve/forums/a/tpc/f/8300945231/m/425006074831">TextMateでASファイルにBOMを加えてみる</a>などいろいろ試したんですが全然駄目で、数時間を無駄にしようとしていたそのとき、自分のミスに気がつきました。
</p>
<p>
<img src="http://journal.reallyenglish.com/2009/11/20/Killer.png" alt="Killer.png" height="622" width="575" />
</p>
<p>
画像のように、どうやら何かの拍子で誤ってLibraryのMovieClip Symbolのひとつに、(Base Classにではなく直接)flash.display.Spriteをリンケージしてしまっていたようです。
</p>
<p>
何故自分でもこんなことをやってしまったのかわかりませんが、これをやってしまうと上記のようにCS4(Mac版)だとpublishはするものの出力が完全沈黙するので、下手をするとはまります（因みにCS３で試したところIDEがクラッシュしました）。たぶんこんなアホなことをやるのは自分だけだろうと思いつつも、もし同じ症状に出くわしたら、一応各Symbolのリンケージをチェックしてみてください。。
</p>
</div>

<div class="lang-section en">
<p>
This is one of my trivial horror stories - the other day I made changes on some Flash stuff I was working on and published the .fla as usual. However, it suddenly stopped working and even worse, it also stopped spitting out any trace/error messages at all. It published fine, but it's broken and dead silent. It seemed to stop recognizing all the ActionScript class files suddenly.
</p>
<p>
Since everything is dead silent I had no clue why it went wrong, I just blindly tried a couple of things I could think of, like checking class pathes/document class linkage, deleting ASOs, and trying to <a href="http://episteme.arstechnica.com/eve/forums/a/tpc/f/8300945231/m/425006074831">add UTF-8 BOM to the AS files (via TextMate)</a>. None of them worked. After wasting a couple of hours like this, I found my mistake.
</p>
<p>
<img src="http://journal.reallyenglish.com/2009/11/20/Killer.png" alt="Killer.png" height="622" width="575" />
</p>
<p>
Like the image above, somehow I mistakenly made a linkage to flash.display.Sprite from one of my hundreds of MovieClip symbol. I typed in flash.display.Sprite not in its Base Class field, but in the Class field. This was the cause of everything.
</p>
<p>
I had no idea why I did this, but anyway I wasted a couple of hours because of the mistake. Usually you don't do something like this but once you did it it may be hard to locate as Flash goes completely silent (In the case of CS4 Mac - when I tried the same on CS3 for testing, it simply crashed). I wrote this note hoping it might help someone who got into the same trap as I did. Perhaps no one else is ever gonna be as dump as me but anyways...
</p>
</div>]]>
        
    </content>
</entry>

<entry>
    <title>On Having Layout</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/10/24/on-having-layout.html" />
    <id>tag:blog.reallyenglish.com,2009://1.15</id>

    <published>2009-10-24T06:49:58Z</published>
    <updated>2009-11-27T19:53:16Z</updated>

    <summary> いまさらかもしれんですが感動しました、これを知っているだけでいままで「なぜ？」と戸惑いながらいろいろ思考錯誤してみるしかなかったIE6(と7)のCSSの問題が結構な確率で解決するように思います; 　 On Having Layout　(http://www.satzansatz.de/cssd/onhavinglayout.html) ものすごくおおざっぱに理解したところを反芻させてもらうと; IEにおいてはHTMLの要素に専用の「隠し」パラメータ &quot;hasLayout&quot;というものが存在する これがある要素に対してOn(true)になっているかなっていないかで、その要素の挙動が大きく変化する hasLayoutはデフォルトでは決められた少数の要素でしかOnになっていない（詳しくは本文参照）。何といっても、一番よく使われると思われるdiv要素でOnになっていない hasLayoutは特定のCSSのプロパティを指定してやることでOnにできるので、hasLayoutがOffになっている要素でこれを恣意的にやってやることによってIEにおける他のブラウザとの表示不一致の問題の矯正が可能な場合がある（その逆も真） といった話だと思います。hasLayoutのOn/Offが実際にどのような影響を及ぼすかについては本文にいくつかの例がリストとしてあがっています（まだincompleteな状態とのことです、具体例を全てあげていくのは困難なのではないでしょうか）。自分も良くわからないままに実際に試してみただけなのですが、div要素やp要素のhasLayoutをOnにしてやることで、IE6/7でのFirefox3との表示の不一致の問題の多く(margin, float関連)が解決したので驚きました。今では、CSSの編集時にIEで何か問題が起こると、ひとまずこのhasLayoutのOn/Offを試すようにしています。...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="css" label="CSS" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="html" label="HTML" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ie" label="IE" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>
いまさらかもしれんですが感動しました、これを知っているだけでいままで「なぜ？」と戸惑いながらいろいろ思考錯誤してみるしかなかったIE6(と7)のCSSの問題が結構な確率で解決するように思います;
　</p>
<p>
<a href="http://www.satzansatz.de/cssd/onhavinglayout.html">On Having Layout　(http://www.satzansatz.de/cssd/onhavinglayout.html)</a>
</p>
<p>
ものすごくおおざっぱに理解したところを反芻させてもらうと;
</p><ul>
<li>IEにおいてはHTMLの要素に専用の「隠し」パラメータ "hasLayout"というものが存在する</li>
<li>これがある要素に対してOn(true)になっているかなっていないかで、その要素の挙動が大きく変化する</li>
<li>hasLayoutはデフォルトでは決められた少数の要素でしかOnになっていない（詳しくは本文参照）。何といっても、一番よく使われると思われるdiv要素でOnになっていない</li>
<li>hasLayoutは特定のCSSのプロパティを指定してやることでOnにできるので、hasLayoutがOffになっている要素でこれを恣意的にやってやることによってIEにおける他のブラウザとの表示不一致の問題の矯正が可能な場合がある（その逆も真）</li>
</ul>
といった話だと思います。hasLayoutのOn/Offが実際にどのような影響を及ぼすかについては本文にいくつかの例がリストとしてあがっています（まだincompleteな状態とのことです、具体例を全てあげていくのは困難なのではないでしょうか）。自分も良くわからないままに実際に試してみただけなのですが、div要素やp要素のhasLayoutをOnにしてやることで、IE6/7でのFirefox3との表示の不一致の問題の多く(margin, float関連)が解決したので驚きました。今では、CSSの編集時にIEで何か問題が起こると、ひとまずこのhasLayoutのOn/Offを試すようにしています。

]]>
        <![CDATA[<p>
IEにおいてこのhasLayoutをOnにする為に、要素に対してCSSのどのプロパティを指定してやればよいのかという話も本文に詳しく解説されていますが、1.)一番無害に、2.)このhackによって他のブラウザでちゃんと表示できているものを（将来的にも）壊さないようするにという観点から、IEのconditional commentsを用いて、下記のようなCSSクラスをつくって適用する方法が紹介されていました。
</p>

<pre><code>&lt;!--[if lt IE 7]&gt;
&lt;style&gt;
 /* style for IE6 + IE5.5 + IE5.0 */
 .gainlayout { height: 0; }
&lt;/style&gt;
&lt;![endif]--&gt;

&lt;!--[if IE 7]&gt;
&lt;style&gt;
 .gainlayout { zoom: 1; }
&lt;/style&gt;
&lt;![endif]--&gt;</code></pre>

<p>
IE5、IE6ではheightプロパティを、IE7ではzoomプロパティを指定してやることによって、恣意的にhasLayoutをトリガーしています。
</p>

<p>
自分はElementひとつひとつにgainlayoutのクラスを適用していくのは大変だと感じたので、下記のようにやることにしました（実際はIEのconditional commentsで別cssをよみこんでます）。
</p>

<pre><code>/* for IE6 */
#idA, #idB, #idC,
.classA, .classB, .classC{
height:0; /* gain layout */
}</code></pre>

<pre><code>/* for IE7 */
#idA, #idB, #idC,
.classA, .classB, .classC{
zoom:1; /* gain layout */
}</code></pre>

<p>
あまりに大雑把な理解なので詳細は本文を参照されることをおすすめします。特にIE6完全対応を迫られているような状況では知ってると知ってないでえらい違いなのではないでしょうか、エディターのみなさんに感謝です。
</p>

<h4>追記 (2009.11.20)</h4>
<p>
あとは自分は下記の２エントリーがとても参考になりました、やはりこういったものは場当たり的にひとつひとつ直していくと大変なことになるので、あるていど体系的な理屈と対処法を理解していたほうが圧倒的にスピードがあがりますね。
<ul>
<li><a href="http://warpspire.com/tipsresources/web-production/css-column-tricks/">Top reasons your CSS columns are messed up</a> on <a href="http://warpspire.com/">Warpspine</a></li>
<li><a href="http://net.tutsplus.com/tutorials/html-css-techniques/9-most-common-ie-bugs-and-how-to-fix-them/">9 Most Common IE Bugs and How to Fix Them</a> on <a href="http://net.tutsplus.com/">Nettuts+</a></li>
</ul>
</p>]]>
    </content>
</entry>

<entry>
    <title>FreeBSD/Jailを使用したプログラマのための仮想環境 - １</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/10/21/freebsd-jail-for-programmer-1.html" />
    <id>tag:blog.reallyenglish.com,2009://1.7</id>

    <published>2009-10-21T01:08:56Z</published>
    <updated>2009-11-29T19:58:57Z</updated>

    <summary>reallyenglishでは、開発環境、また一部のプロダクション環境でFreeBSDのJail機能を使っています。このJailを使うことによりシンプルで柔軟な開発環境が構築できます。 &#8220;FreeBSD&#8221;と聞いて、「ああ、関係ないや」と思われた方へ。 ちょっとだけでも読んでみてください。JailのためだけでもFreeBSDを導入する価値があると思っています。もし、FreeBSDの導入が無理だとしても考え方自体は他のFreeBSDのJail以外の仮想環境でも使えるはずです。 前提 Webシステム開発ではたくさんのサーバソフトウェアが必要です。システムの中心部であるPHPやRuby On Railsといったアプリケーションサーバや、データを格納するデータベースサーバは最低限必要でしょう。またロードバランサやメールサーバといったものも必要なることもあります。 また開発時にはGitやSubversionのようなSCMや、コミュニケーションのためのIRCサーバなども必要かもしれません。同じような環境を開発者やテスター毎、開発拠点毎に設置する必要があることも珍しくないでしょう。さらに、一つのWebアプリケーションでも、プロダクション用や、開発用と複数のバージョンを持ちつつ同時に開発するのもよくあることです。 さらに、予算やスペースの関係で、プロダクションサーバでは多くの物理的なサーバで行っていることを開発環境では少ない台数のサーバで賄わないといけない、ということもよくあることでしょう。 そのような様々なことから、ちょっとしたWebサービスの開発でも、かなりの複雑な環境が必要になることがわかります。 そう言った複雑な環築をなるべくシンプルに構築するためにreallyenglishではFreeBSDのJailを使用した仮想環境を使っています。 基本的な方針 まず、基本的な方針として、１サービス=１仮想環境にします。これはプロダクション環境でも、開発環境でも同じです。つまり、Apacheでも、PostgreSQLでも、Memcacheでも、Postfixでも、Gitでも、とにかくサーバ的なものは必ず一つの仮想環境にしてしまいます。 つまり「このサービスは軽いから、他のサービスと同じところで動かしちゃおう」的なことをやめました。何か新しく必要になったら、仮想環境を新規で作成しそこにインストールします。ちょっとした実験的なサービスを入れる場合でも同じです。「Nginx試したい。じゃー、Jail作ってそこでやろう。」と言った感じです。 また、同じサービスでも、用途が違えば別に仮想環境を作ります。例えば、Apache等のWebサーバはVirtual Host機能を使うことにより1つのWebサーバを複数の用途として使えますが、そういうこともやめました。 狙いは２つです。 設定をシンプルにする。一つのサーバで、あれもこれもしようとすると、どうしても設定ファイルが複雑にいなってしまいます。1サービス1Jailとすると必然的に設定はかなりシンプルになります。また、設定をシンプルにすることでPuppetと言ったツールも導入しやすくなります。 ハードウェアとサービス、サービス間を疎結合にする。粗結合にしておくと色々なことがとてもフレキシブルになります。例えば、一つのサービスの負荷が非常に高くなり他のサービスに影響を与え始めた。こういう場合、別のハードウェアを用意し、そのサービスだけ移動する、と言ったことがよく行われます。このときに1サービス = 1 仮想環境ならその仮想環境をコピー（移動）するだけで完了します。同一のネットワーク内で移動するだけなら、仮想環境のIP addressの付け替えさえ必要ありません。 いちいち仮想環境を作る。というのは一見めんどくさいようにも思えますし、リソース的にも無駄が多そうだ、と思われるかもしれません。しかし、FreeBSDのJailとその管理ツールを使用するとその辺は驚くほど問題になりません。 次回、実際にどう使っているかを紹介します。 続く...</summary>
    <author>
        <name>Masatomo Nakano</name>
        <uri>http://twitter.com/masatomon</uri>
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="environment" label="Environment" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="freebsd" label="FreeBSD" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jail" label="Jail" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>reallyenglishでは、開発環境、また一部のプロダクション環境でFreeBSDのJail機能を使っています。このJailを使うことによりシンプルで柔軟な開発環境が構築できます。</p>

<p>&#8220;FreeBSD&#8221;と聞いて、「ああ、関係ないや」と思われた方へ。</p>

<p>ちょっとだけでも読んでみてください。JailのためだけでもFreeBSDを導入する価値があると思っています。もし、FreeBSDの導入が無理だとしても考え方自体は他のFreeBSDのJail以外の仮想環境でも使えるはずです。</p>

<h2>前提</h2>

<p>Webシステム開発ではたくさんのサーバソフトウェアが必要です。システムの中心部であるPHPやRuby On Railsといったアプリケーションサーバや、データを格納するデータベースサーバは最低限必要でしょう。またロードバランサやメールサーバといったものも必要なることもあります。</p>

<p>また開発時にはGitやSubversionのようなSCMや、コミュニケーションのためのIRCサーバなども必要かもしれません。同じような環境を開発者やテスター毎、開発拠点毎に設置する必要があることも珍しくないでしょう。さらに、一つのWebアプリケーションでも、プロダクション用や、開発用と複数のバージョンを持ちつつ同時に開発するのもよくあることです。</p>

<p>さらに、予算やスペースの関係で、プロダクションサーバでは多くの物理的なサーバで行っていることを開発環境では少ない台数のサーバで賄わないといけない、ということもよくあることでしょう。</p>

<p>そのような様々なことから、ちょっとしたWebサービスの開発でも、かなりの複雑な環境が必要になることがわかります。</p>

<p>そう言った複雑な環築をなるべくシンプルに構築するためにreallyenglishではFreeBSDのJailを使用した仮想環境を使っています。</p>

<h2>基本的な方針</h2>

<p>まず、基本的な方針として、１サービス=１仮想環境にします。これはプロダクション環境でも、開発環境でも同じです。つまり、Apacheでも、PostgreSQLでも、Memcacheでも、Postfixでも、Gitでも、とにかくサーバ的なものは必ず一つの仮想環境にしてしまいます。</p>

<p>つまり「このサービスは軽いから、他のサービスと同じところで動かしちゃおう」的なことをやめました。何か新しく必要になったら、仮想環境を新規で作成しそこにインストールします。ちょっとした実験的なサービスを入れる場合でも同じです。「Nginx試したい。じゃー、Jail作ってそこでやろう。」と言った感じです。</p>

<p>また、同じサービスでも、用途が違えば別に仮想環境を作ります。例えば、Apache等のWebサーバはVirtual Host機能を使うことにより1つのWebサーバを複数の用途として使えますが、そういうこともやめました。</p>

<p>狙いは２つです。</p>

<ul>
<li>設定をシンプルにする。一つのサーバで、あれもこれもしようとすると、どうしても設定ファイルが複雑にいなってしまいます。1サービス1Jailとすると必然的に設定はかなりシンプルになります。また、設定をシンプルにすることでPuppetと言ったツールも導入しやすくなります。</li>
<li>ハードウェアとサービス、サービス間を疎結合にする。粗結合にしておくと色々なことがとてもフレキシブルになります。例えば、一つのサービスの負荷が非常に高くなり他のサービスに影響を与え始めた。こういう場合、別のハードウェアを用意し、そのサービスだけ移動する、と言ったことがよく行われます。このときに1サービス = 1 仮想環境ならその仮想環境をコピー（移動）するだけで完了します。同一のネットワーク内で移動するだけなら、仮想環境のIP addressの付け替えさえ必要ありません。</li>
</ul>

<p>いちいち仮想環境を作る。というのは一見めんどくさいようにも思えますし、リソース的にも無駄が多そうだ、と思われるかもしれません。しかし、FreeBSDのJailとその管理ツールを使用するとその辺は驚くほど問題になりません。</p>

<p>次回、実際にどう使っているかを紹介します。</p>

<p><a href="/2009/11/29/freebsd-jail-for-programmer-2.html">続く</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>FAQ for SWFObject is a must-read</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/09/01/faq-for-swfobject-is-a-must-read.html" />
    <id>tag:blog.reallyenglish.com,2009://1.13</id>

    <published>2009-08-31T20:36:54Z</published>
    <updated>2009-11-20T12:49:36Z</updated>

    <summary> SWFObjectのFAQはいけてますね、FlashをHTMLにembedするにあたっての陥りやすい罠が網羅されている印象です。実質、FAQの項目の多くが SWFObject自体の問題というよりはブラウザのバグ等が原因のため、同ライブラリを使う使わないに関わらず起こるもののような気がするのですが、SWFObjectが非常に多くの人達に使われているため、ここにそのあたりの質問とその応答の結果として蓄積されたノウハウが一番端的に集まっているように思います。日々様々な（時にはいわれのない）「おい、これ動かんぞ」の問い合わせに開発者の方やコミュニティーのみなさんが反応してくれている状況を想像するに、様々なライブラリ一般を公開して維持してくれている全てのみなさんへの尊敬の念が深まります。...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="actionscript" label="ActionScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="css" label="CSS" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flash" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flex" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="html" label="HTML" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>
<a href="http://code.google.com/p/swfobject/wiki/faq">SWFObjectのFAQ</a>はいけてますね、FlashをHTMLにembedするにあたっての陥りやすい罠が網羅されている印象です。実質、FAQの項目の多くが <a href="http://code.google.com/p/swfobject/">SWFObject</a>自体の問題というよりはブラウザのバグ等が原因のため、同ライブラリを使う使わないに関わらず起こるもののような気がするのですが、SWFObjectが非常に多くの人達に使われているため、ここにそのあたりの質問とその応答の結果として蓄積されたノウハウが一番端的に集まっているように思います。日々様々な（時にはいわれのない）「おい、これ動かんぞ」の問い合わせに開発者の方やコミュニティーのみなさんが反応してくれている状況を想像するに、様々なライブラリ一般を公開して維持してくれている全てのみなさんへの尊敬の念が深まります。
</p>]]>
        <![CDATA[<p>
最近<a href="/2009/08/25/learning-mxml-as-a-fla-guy.html">はじめてFlex Frameworkを用いた小さなテストツールの作成に関わった</a>のですが、ひととおり形になりdeploy用のファイルを構成するにあたって、Flex Buliderが生成するごちゃごちゃしたHTMLが嫌でSWFObjectを使った自前のものを使ったら、Firefox 3で.swfが表示されずに多少悩んでしまいました。原因はSWFObject FAQの1番;
</p>
<blockquote>
because Firefox (or: any Gecko based browser) in standards compliant mode (or: using a valid DOCTYPE) interprets percentages in a very strict way (to be precise: the percentage of the height of its parent container, which has to be set explicitly): 
</blockquote>
<p>
だったのですが、これ自分も過去に経験してたのにまた忘れてました。Gecko系のブラウザで<a href="http://hp.vector.co.jp/authors/VA028872/webtech/stdmode.html">標準モード</a>のときは、object(embed)要素のheightを100%にするだけでは駄目で、その祖先要素(html, body含む)の全てのheightをCSSで明示的に指定しないと表示がおかしくなります。
</p>
<div>(因みに自分のSWFObjectを使ったFlexアプリ用簡素版HTMLテンプレートはこんな感じです)</div>
<pre><code class="language-html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;title&gt;The Title&lt;/title&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;meta http-equiv="Content-Style-Type" content="text/css" /&gt;
&lt;meta http-equiv="Content-Script-Type" content="text/javascript" /&gt;
&lt;link rel="stylesheet" type="text/css" href="history/history.css" /&gt;
&lt;style type="text/css"&gt;
	html, body {height:100%;}
	body {margin:0; padding:0; background-color:#869ca7; overflow:hidden;}
	img {border-style:none;}
	#container {width:100%;height:100%;}
	#altContents {margin:1em;}
	#altContents div {margin-bottom:0.5em;}
&lt;/style&gt;
&lt;script type="text/javascript" src="history/history.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="swfobject.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
//&lt;![CDATA[
	var swfUrl = "Main.swf";
	var containerID = "container";
	var w = "100%";
	var h = "100%";
	var requiredVersion = "9.45.0";
	var expressInstallSwfUrl = "expressInstall.swf";
	var flashvars = {};
	flashvars.userAgent = navigator.userAgent;
	var params = {};
	params.quality = "high";
	params.bgcolor = "#869ca7";
	params.allowScriptAccess = "sameDomain";
	var attributes = {};
	attributes.id = "main";
	attributes.name = "main";
	swfobject.embedSWF(swfUrl, containerID, w, h, requiredVersion, expressInstallSwfUrl, flashvars, params, attributes);
//]]&gt;
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id="container"&gt;
		&lt;div id="altContents"&gt;
			&lt;div&gt;To view the contents of the page, please turn JavaScript on, and install the latest version of Adobe Flash Player from the link below.&lt;/div&gt;
			&lt;div&gt;&lt;a href="http://www.adobe.com/go/getflashplayer"&gt;&lt;img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /&gt;&lt;/a&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>
新しいことを学んでいるときは昔はまったこともぽろっと忘れてしまうものですね。自分の過去の経験から、個人的にはFAQの6番、24番等も要チェックかと思います。
</p>]]>
    </content>
</entry>

<entry>
    <title>Learning .mxml (as a .fla guy)</title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/08/25/learning-mxml-as-a-fla-guy.html" />
    <id>tag:blog.reallyenglish.com,2009://1.10</id>

    <published>2009-08-25T01:44:17Z</published>
    <updated>2009-08-25T22:32:54Z</updated>

    <summary> 他のActionScriptを（も）書いているtechチームメンバーと違い、.flaファイルを使ったFlash IDEを用いてのコンテンツ制作しかろくにできなかった自分ですが、ここ数日、非常に小さいながらもFlex Framework/.mxmlを使った仕事(.mxmlで書かれたテスティングツールのUIデザイン)をやらせてもらっていて、今更なんとか勉強しているところです。 Flex Builderは稀にASエディタ/デバッガとしてしか使うくらいでしたし(今は主にFDTとFlashDevelopをつかってます)、reallyenglishに参加させてもらう前はどちらかというと表現重視のものをつくってきた経緯から、傲慢にも自分がFlexを覚えるメリットは大してないだろうと考えていました（実際.mxml主体の制作方法ではものすごく難しい制作ケースがほとんどだったと思います）。しかし今回Flex Frameworkを実際に少し勉強してみて、逆にこの充実したFrameworkの恩恵をうまく使えばいろいろなことが本当に楽にできそうだ（逆にいうと恩恵をうけないと大変すぎて無理そう）といったケースが多くあるだろうということも実感しました。 このAdobeのチュートリアルなどをみるとおおこれは簡単そう、と感動しましたし、何よりも.mxmlを使えばソースがテキストだけで完結できるケースが増えるので見通しがよくなるのが魅力だと思います。これからは二つの制作方法の使いどころを把握してうまいこと組み合わせて使っていけるようになれたらなと考えています。 (。。という流れからもXFLには超期待しているんですが最近どうなっているのでしょうか？　あと最初はなんじゃこりゃと思っていたFlash Catalystも今はぜひ使ってみたいと思っています。) さて本題です。Flex FrameworkのHTMLライクなレイアウトの仕組みもぱっと見思ったより簡単そうでよかったのですが、Flex用のCSSもちゃんと充実してるんですね。検索したら非常にありがたい参考サイトがあったので、紹介させてもらいます。 fillcolors - デザインスキームと一緒にCSSのソースをつけてくれているので大変参考になりそう Flex 3.0 CSS Properties List - 見やすそうです！ 追記: Flex BuilderがFlash Builderと再ブランディングされることになり、ますます用語の使い方に迷いますが、下記の記事はFlexって結局なんだったっけ、と再勉強するにあたって非常に助けになりました。 Ginormous: The Difference Between Flex and Flash InfoQ: Top 10 Adobe Flex Misconceptions...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="actionscript" label="ActionScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flash" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flex" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<p>
他のActionScriptを（も）書いているtechチームメンバーと違い、.flaファイルを使ったFlash IDEを用いてのコンテンツ制作しかろくにできなかった自分ですが、ここ数日、非常に小さいながらもFlex Framework/.mxmlを使った仕事(.mxmlで書かれたテスティングツールのUIデザイン)をやらせてもらっていて、今更なんとか勉強しているところです。
</p>
<p>
Flex Builderは稀にASエディタ/デバッガとしてしか使うくらいでしたし(今は主に<a href="http://fdt.powerflasher.com/">FDT</a>と<a href="http://www.flashdevelop.org/">FlashDevelop</a>をつかってます)、<a href="http://www.reallyenglish.com">reallyenglish</a>に参加させてもらう前はどちらかというと表現重視のものをつくってきた経緯から、傲慢にも自分がFlexを覚えるメリットは大してないだろうと考えていました（実際.mxml主体の制作方法ではものすごく難しい制作ケースがほとんどだったと思います）。しかし今回Flex Frameworkを実際に少し勉強してみて、逆にこの充実したFrameworkの恩恵をうまく使えばいろいろなことが本当に楽にできそうだ（逆にいうと恩恵をうけないと大変すぎて無理そう）といったケースが多くあるだろうということも実感しました。
</p>
<p>
<a href="http://learn.adobe.com/wiki/display/Flex/Part+I.+Creating+a+Simple+RIA">このAdobeのチュートリアル</a>などをみるとおおこれは簡単そう、と感動しましたし、何よりも.mxmlを使えばソースがテキストだけで完結できるケースが増えるので見通しがよくなるのが魅力だと思います。これからは二つの制作方法の使いどころを把握してうまいこと組み合わせて使っていけるようになれたらなと考えています。
<p>
(。。という流れからも<a href="http://blogs.adobe.com/jnack/2008/03/flash_moving_to.html">XFL</a>には超期待しているんですが最近どうなっているのでしょうか？　あと最初はなんじゃこりゃと思っていた<a href="http://labs.adobe.com/technologies/flashcatalyst/">Flash Catalyst</a>も今はぜひ使ってみたいと思っています。)
</p>
<p>
さて本題です。Flex FrameworkのHTMLライクなレイアウトの仕組みもぱっと見思ったより簡単そうでよかったのですが、Flex用のCSSもちゃんと充実してるんですね。検索したら非常にありがたい参考サイトがあったので、紹介させてもらいます。
<ul>
<li><a href="http://www.fillcolors.com/">fillcolors</a> - デザインスキームと一緒にCSSのソースをつけてくれているので大変参考になりそう</li>
<li><a href="http://www.digitalchickenscratch.com/misc/flex-css/">Flex 3.0 CSS Properties List</a> - 見やすそうです！</li>
</ul>
</p>
<p>
追記:<br />
<a href="http://www.webkitchen.be/2009/05/16/next-version-of-flex-builder-will-be-named-flash-builder-4/">Flex BuilderがFlash Builderと再ブランディングされる</a>ことになり、ますます用語の使い方に迷いますが、下記の記事はFlexって結局なんだったっけ、と再勉強するにあたって非常に助けになりました。
<ul>
<li><a href="http://theresidentalien.typepad.com/ginormous/2009/02/the-difference-between-flex-and-flash.html">Ginormous: The Difference Between Flex and Flash</a></li>
<li><a href="http://www.infoq.com/news/2007/12/top-10-flex-misconceptions">InfoQ: Top 10 Adobe Flex Misconceptions</a></li>
</ul>
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Highlighting Text in TextField  </title>
    <link rel="alternate" type="text/html" href="http://journal.reallyenglish.com/2009/08/23/highlighting-text-in-textfield.html" />
    <id>tag:blog.reallyenglish.com,2009://1.8</id>

    <published>2009-08-23T04:40:20Z</published>
    <updated>2009-12-20T20:34:51Z</updated>

    <summary> Manipulating text presentation in a Flash interface is a very common task when developing a interface for learning applications at reallyenglish. &quot;Highlighting&quot; a certain parts of the text in a Flash TextField is just one of them and unlike...</summary>
    <author>
        <name>Go Kameda</name>
        
    </author>
    
        <category term="Tips / Tutorials" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="actionscript" label="ActionScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flash" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://journal.reallyenglish.com/">
        <![CDATA[<div class="lang-section en">
<p>
Manipulating text presentation in a Flash interface is a very common task when developing a interface for learning applications at <a href="http://www.reallyenglish.com/">reallyenglish</a>.  "Highlighting" a certain parts of the text in a Flash TextField is just one of them and unlike doing it in HTML, it could be a bit cumbersome task sometimes. This time I tried to modularize the functionality.
</p>
<p>
<a href="/2009/08/23/TextHiliter/demo/" onclick="return reOpenPlainWindow('/2009/08/23/TextHiliter/demo/', 'TextHiliter', 902, 486);">View Demo</a><br />
<a href="/2009/08/23/TextHiliter/SourceFiles.zip">Source files  (.zip, 356KB)</a>
</p>
<h4>Rough description of how to use (please refer to the demo and the source code as well);</h4>
<pre><code class="language-actionscript"> // Create a TextHiliter class instance, passing references for the TextField and a Sprite to draw hilighting marker;
_textHiliter = new TextHiliter(refTextField, refCanvas);

// Hilight the 1st to 4th letters, with #C4E1FF (100% alpha) marker
_textHiliter.hilite(0, 4, 0xC4E1FF, 1);

// Hilight the letters "unable to stop herself to assist her" between "Margaret, "　(please note the spaces)  and ", was involuntarily" with #D3FD2D (100% alpha) marker
// The current implementation hilights the 1st match only
_textHiliter.hiliteByLetters("unable to stop herself to assist her",  0xD3FD2D, 1, "Margaret, ", ", was involuntarily");</code></pre>

<p>
Although it's still under improvement, I think that the logic for extracting area of certain part of the text can be applied to some other purposes. (And please enlighten me if you know a better way of doing it..!)
</p>

<p>
<strong>2009/12/20:</strong><br />
Made the following changes.
</p><ul>
<li>Changed hilite() method so that it does not include the character specified by the argument "end(index)". Now it takes effect to the part specified by start and all characters up to end - 1, just like String.substring() method.</li>
<li>Changed the Demo so that the text can be highlighten just by selecting a certain part of it.</li>
</ul>


</div>

<div class="lang-section ja">
<p>
<a href="http://www.reallyenglish.com/">reallyenglish</a>に参加してから、ActionScriptでのテキストの加工（特に表示面での加工）を行うことが多くなりました。ダイナミックテキストの特定の複数箇所をハイライト（マーキング）するといった処理もその一つです。HTMLだと楽勝ですが、Flashの場合やってみたらかなりめんどくさい感じだったのでこの機能を切り出したものをつくってみました。
</p>
<p>
<a href="/2009/08/23/TextHiliter/demo/" onclick="return reOpenPlainWindow('/2009/08/23/TextHiliter/demo/', 'TextHiliter', 902, 486);">View Demo</a><br />
<a href="/2009/08/23/TextHiliter/SourceFiles.zip">Source files (.zip, 356KB)</a>
</p>
<h4>TextHiliterクラスのおおまかな使い方（詳しくはデモ及びソースコードを参照）;</h4>
<pre><code class="language-actionscript">// TextField、及び描画用Spriteの参照を引数にTextHiliterのインスタンスをつくる
_textHiliter = new TextHiliter(refTextField, refCanvas);

// 1文字目から4文字目までを、#C4E1FF、100%アルファでハイライトする場合
_textHiliter.hilite(0, 4, 0xC4E1FF, 1);

// "Margaret, " と ", was involuntarily"(スペースに注意)　という文字列に挟まれた "unable to stop herself to assist her" という文字列を、#D3FD2D、100%アルファでハイライトする場合
// (現状の実装では、条件を満たすものが複数あった場合も、一番初めにマッチしたものにしか適用されないです）
_textHiliter.hiliteByLetters("unable to stop herself to assist her",  0xD3FD2D, 1, "Margaret, ", ", was involuntarily");</code></pre>

<p>
まだ発展途上ですが、TextField内の文字列のエリアを取得する部分のロジックは他の用途にも応用できると思うので、何かの参考にでもなれば嬉しいです。あともっといいやり方があれば教えてください。。！
</p>

<p>
<strong>2009/12/12　追記:</strong><br />
下記を変更しました。
</p><ul>
<li>hilite()メソッドをString.substring()メソッドと同様、startで指定したindexからendで指定したindexの一文字前までハイライトするように変更（以前はendで指定したindexの文字を含んでました、ごめんなさい）</li>
<li>デモにおいて、テキストをセレクトするとセレクトした部分がハイライトされるよう変更</li>
</ul>


</div>]]>
        
    </content>
</entry>

</feed>

