Skip to content

Instantly share code, notes, and snippets.

@nojima
Last active November 23, 2016 08:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nojima/3a3d911d11194a540948d09826713731 to your computer and use it in GitHub Desktop.
Save nojima/3a3d911d11194a540948d09826713731 to your computer and use it in GitHub Desktop.

IPsec with ip command

ip コマンドを使った IPsec 通信の設定方法を説明する。 以下で紹介する方法は

  • 事前に何らかの方法で鍵を共有する必要がある
  • リピート攻撃を防ぐために鍵を定期的に更新するための仕組みが必要となる

という問題があるため、真面目な用途に使う場合はちゃんと IKE とかを使ったほうがよいと思う。

ip xfrm

Linux にはデフォルトで IPsec 通信を行う機能が備わっており、ip xfrm コマンドで操作できる。 ip xfrm で操作できるオブジェクトは以下の2つ。

  • State
    • IPsec 通信に使うパラメータを保持するオブジェクト。
    • 通信に使う暗号化方式、認証方式、共有鍵などを保持している。
    • ホストの組ごとに2つ(順方向、逆方向)作る。
    • SPI という state を識別するためのインデックスが割り振られている。
      • SPI は自分だけではなく、通信相手にも送られるため、事前にどの SPI を使うか合意をとっておく必要がある。
      • IKE を使う場合は state の共有などはよしなにやってくれるが、ip xfrm を直に叩く場合は何とかして state を事前に共有しておく。
    • sudo ip xfrm state で一覧を見れる。
    • src と dst の組のハッシュ表で管理されているため、大量に作っても性能に問題はないはず。
  • Policy
    • IPsec 通信をするのか、するとしたらどの State を使うのかを決めるためのルール。
    • マッチに使える項目は自分や相手の IP アドレス、利用するインターフェイス、上位のプロトコルなど。
    • sudo ip xfrm policy で一覧を見れる。
    • priority を持つことができ、マッチする policy の中で最も priority の小さいものが利用される。
    • Policy はリストを普通に上からチェックしていく方式なので、大量に policy を作るとパフォーマンス上の問題がある。

設定例

IPアドレス 1.1.1.1 を持つホストと、IPアドレス 2.2.2.2 を持つホストの間で eth1 で IPsec 通信を行う。 以下は 1.1.1.1 の方のホストで打つコマンド。

ip xfrm state add \
    src "1.1.1.1" \
    dst "2.2.2.2" \
    proto "esp" \
    spi "1234" \
    auth "hmac(sha1)" "0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
    enc "cbc(aes)" "0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
    reqid "42" \
    mode "transport"

ip xfrm state add \
    src "2.2.2.2" \
    dst "1.1.1.1" \
    proto "esp" \
    spi "4321" \
    auth "hmac(sha1)" "0xYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" \
    enc "cbc(aes)" "0xYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" \
    reqid "42" \
    mode "transport"

ip xfrm policy add \
    dev "eth1" \
    dir "out" \
    priority 1000 \
    tmpl proto "esp" reqid "42"

ip xfrm policy add \
    dev "eth1" \
    dir "in" \
    priority 1000 \
    tmpl proto "esp" reqid "42"
  • state と policy は out 方向と in 方向でそれぞれ作成する必要がある。
  • この例では、state に以下のパラメータを指定している。(他にも指定できるパラメータはある)
    • src, dst - 送信元と送信先の IP アドレス。レンジは指定できない。
    • proto - 暗号化に使うプロトコル。多分 esp ぐらいしか使わない。
    • spi - state を識別するためのインデックス。通信相手の対応する state も同じ SPI を持つ必要がある。
    • auth - 認証に使うアルゴリズムと鍵。鍵の長さはアルゴリズム毎に決まっているので注意。
    • enc - 暗号化に使うアルゴリズムと鍵。鍵の長さはアルゴリズム毎にきまっているので注意。
    • reqid - state をグループ分けするための ID。policy の tmpl に指定する。
    • mode - transport or tunnel。他にも指定できるみたいだけどよくわからない。
  • この例では、policy に以下のパラメータを指定している。(他にも指定できるパラメータはある)
    • dev - 指定したネットワークデバイスを利用するパケットにマッチ。
    • dir - 指定した方法のパケットにマッチ。
    • priority - これが小さい policy から順にマッチして、最初にマッチしたものが使われる。
      • この例では、複数の policy にマッチすることはないので、priority を指定する意味はない。
    • tmpl - マッチしたパケットに適用する state を決めるためのルールを指定する。
      • tmpl で指定した条件に加えて SPI でもマッチするような state が利用される。
      • tmpl にマッチする state が存在しない場合、そのパケットは drop される。
    • この例では指定していないが、src, dst でマッチする送信元/送信先アドレスを指定できる。 policy の場合はレンジを指定できる。

2.2.2.2 の方で打つコマンドは以下のようになる。 この例の場合、順番以外は 1.1.1.1 で打つコマンドと完全に一致している。

ip xfrm state add \
    src "2.2.2.2" \
    dst "1.1.1.1" \
    proto "esp" \
    spi "4321" \
    auth "hmac(sha1)" "0xYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" \
    enc "cbc(aes)" "0xYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" \
    reqid "42" \
    mode "transport"

ip xfrm state add \
    src "1.1.1.1" \
    dst "2.2.2.2" \
    proto "esp" \
    spi "1234" \
    auth "hmac(sha1)" "0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
    enc "cbc(aes)" "0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
    reqid "42" \
    mode "transport"

ip xfrm policy add \
    dev "eth1" \
    dir "out" \
    priority 1000 \
    tmpl proto "esp" reqid "42"

ip xfrm policy add \
    dev "eth1" \
    dir "in" \
    priority 1000 \
    tmpl proto "esp" reqid "42"

この例では2つのホスト間での IPsec 通信を扱ったが、3つ以上のホストで同様の IPsec 通信を行う場合は、policy は上の例のままにしておいて、state だけを増やせばよい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment