Cisco VPNへの接続中にローカルLANアクセスを許可する方法は?


82

Cisco VPNに接続しているときにローカルLANアクセスを維持するにはどうすればよいですか?

Cisco VPNを使用して接続する場合、サーバーはクライアントにローカルLANアクセスを防止するよう指示する必要があります。

このサーバー側オプションをオフにできないと仮定した場合、Cisco VPNクライアントとの接続中にローカルLANアクセスを許可するにはどうすればよいですか?


以前は、たとえば、次のように、より高いメトリックでLANトラフィックをキャプチャするルートが追加されるだけの問題だと考えていました。

  Network 
Destination      Netmask        Gateway       Interface  Metric
   10.0.0.0  255.255.0.0       10.0.0.3        10.0.0.3      20  <--Local LAN
   10.0.0.0  255.255.0.0  192.168.199.1  192.168.199.12       1  <--VPN Link

そして、10.0.x.x -> 192.168.199.12ルートを削除しようとしても効果はありません。

>route delete 10.0.0.0
>route delete 10.0.0.0 mask 255.255.0.0
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 192.168.199.12
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 0x3

そして、それはまだルーティングの問題にすぎないかもしれませんが、ルートを追加または削除しようとすると失敗します。

Cisco VPNクライアントドライバーは、ネットワークスタック内で何を実行して、ローカル管理者がマシンを管理する機能を無効にしますか?

Cisco VPNクライアントはマジックを使用できません。それはまだ私のコンピューターで実行されているソフトウェアです。マシンのネットワークに干渉するためにどのメカニズムを使用していますか?IP / ICMPパケットがネットワークに到着するとどうなりますか?ネットワークスタックのどこでパケットが食べられますか?

こちらもご覧ください


編集:まだ試したことのないもの:

>route delete 10.0.*

更新: CiscoはAnyConnect(HTTP SSLベースのVPN)を支持して古いクライアントを放棄しているため、この問題は未解決であり、歴史の遺物として残すことができます。

今後、新しいクライアントで同じ問題の解決を試みることができます


1
VPNリンクのメトリックは低いため、ローカルルートの前に試行されます。ローカルLANのメトリックを増やすと、ほとんどの場合ローカルLANが無効になります。VPNがすべてのトラフィックスイッチングをトンネリングするように構成されていない場合、ホームサブネットがソリューションになる可能性があります。このVPNを介してアクセスするために必要なIPは何ですか?これはVPN側の10.0.0.0全体ですか?
pberlijn

それが問題である可能性が非常に高いようです。私はより高い=より良いのメトリックを考えました
イアン・ボイド


2
シスコAnyConnectはで説明しOpenConnectの代替主に互換性のあるクライアントに置き換えることができますserverfault.com/a/664097/104573
ヴァジム・

回答:


53

Anyconnectの問題は、最初にルーティングテーブルを変更し、次に手動で変更した場合にそれをベビーシットして修正することです。これの回避策を見つけました。バージョン3.1.00495、3.1.05152、3.1.05170、およびおそらく3.1ファミリーの他のすべてで動作します。他のバージョンでも動作する可能性がありますが、少なくとも同様のアイデアは、コードが書き換えられないと仮定して動作するはずです。幸いなことに、シスコはベビーシッターの「baby is awake」コールを共有ライブラリに入れました。そのため、LD_PRELOADを介したvpnagentdによるアクションを防止するという考え方です。

  1. 最初にファイルを作成しますhack.c

    #include <sys/socket.h>
    #include <linux/netlink.h>
    
    int _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv()
    {
      int fd=50;          // max fd to try
      char buf[8192];
      struct sockaddr_nl sa;
      socklen_t len = sizeof(sa);
    
      while (fd) {
         if (!getsockname(fd, (struct sockaddr *)&sa, &len)) {
            if (sa.nl_family == AF_NETLINK) {
               ssize_t n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
            }
         }
         fd--;
      }
      return 0;
    }
    

注:このコードはLinuxでのみ機能します。このソリューションをmacOSマシンに適用するには、macOSに適合したバージョンを参照してください。

  1. 次に、次のようにコンパイルします。

    gcc -o libhack.so -shared -fPIC hack.c
    
  2. libhack.soCiscoライブラリパスにインストールします。

    sudo cp libhack.so  /opt/cisco/anyconnect/lib/
    
  3. エージェントを停止します。

    /etc/init.d/vpnagentd stop
    
  4. 本当にダウンしていることを確認してください

    ps auxw | grep vpnagentd
    

    そうでない場合は、kill -9念のため。

  5. 次にLD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so 、vpnagentdが呼び出される場所を追加して/etc/init.d/vpnagentdを修正し、次のようにします。

    LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so /opt/cisco/anyconnect/bin/vpnagentd
    
  6. 次に、エージェントを起動します。

    /etc/init.d/vpnagentd start
    
  7. AnyConnectが混乱するため、iptablesを修正します。

    iptables-save | grep -v DROP | iptables-restore
    

    特定のLANホストへのアクセスのみを許可するために、ここでさらに高度な操作を行うことができます。

  8. 次に、必要に応じてルートを修正します。例:

    route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
    
  9. それらが実際に存在するかどうかを確認します。

    route -n
    

このハックの以前の単純なバージョンは、「0を返す」だけの機能を提供していました。-そのポスターは、「これまでに観察した唯一の副作用は、vpnagentdがtopによって報告されたCPUの100%を使用していることですが、全体のCPUはユーザー3%、システム20%であり、システムは完全に応答します私はそれを追い詰め、アイドルが両方からすばやく戻ったときにループで2つの選択を行っているようですが、それは読み取りも書き込みもしません-LD_PRELOADで切り取った呼び出しは読み取ることになっていたと思います。それを行うために、しかし今のところ私にとっては十分です。誰かがより良い解決策を持っているなら、共有してください。」

些細なハックの問題は、1つのCPUコアが常に100%になり、vpn接続がアクティブであるかどうかに関係なく、ハードウェアCPUスレッド数を1つずつ効果的に削減することです。コードが行っていた選択は、ルーティングテーブルが変更されたときにvpnagentdデータを送信するnetlinkソケット上にあることに気付きました。vpnagentdは、netlinkソケットに新しいメッセージがあることに気づき、それに対処するためにrouteCallBackHandlerを呼び出しますが、些細なハックは新しいメッセージを消去しないため、何度も何度も呼び出され続けます。上記の新しいコードはネットリンクデータをフラッシュするため、CPUを100%使用する無限ループは発生しません。

何かが機能しない場合はgdb -p $(pidof vpnagentd)、一度添付してください:

b socket
c
bt

そして、どの通話に参加しているかを確認します。次に、どの通話を切りたいかを推測し、hack.cに追加して再コンパイルします。


4
これは天才です。私はそれをOSXで動作させようとしていますが、1つの質問があります:オーバーライドするメソッドの名前がどのようにわかったの_ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEvですか?
ドンターナー14

2
@donturner試しnm /opt/cisco/anyconnect/lib/libvpnagentutilities.dylib | grep routeCallbackHandlerEv、その後、あなたは見つけることができます__ZN25CInterfaceRouteMonitorMac20routeCallbackHandlerEv
McKelvin

私は、gdbでvpnagentdに接続し、さまざまなブレークポイントを設定することでそれを理解しました。
サーシャパチェフ

@McKelvin nm /opt/cisco/anyconnect/lib/libvpnagentutilities.sonm: /opt/cisco/anyconnect/lib/libvpnagentutilities.so: no symbolsUbuntuでAnyConnectを返す ため、シンボルテーブル情報なしで生成されました。どうやってそれを手に入れることができますか?
nephewtom

@SashaPachevシンボル情報なしでvpnagentdをデバッグするにはどうすればよいですか?
-nephewtom

11

これは非常に複雑ですが、VMWare Playerなどを使用して最小限のVMを作成し、その中でCisco AnyConnect VPNクライアントを実行すると、VMWare仮想ネットワークアダプターを使用してルーティングを設定したり、単にCisco SSL VPNを介して必要なリソースにアクセスするためのVMおよび実際のマシンとの間でファイルを「ドラッグ/ドロップ」します。


7

Ian Boydが示唆したように、Shrew Soft VPNソフトウェアも私のためにトリックをしてくれました。

Cisco VPNクライアントプロファイルをインポートできます。Cisco VPN Clientバージョン5.0.05.0290を使用し、Shrew VPN(バージョン2.1.7)をインストールし、Ciscoプロファイルをインポートした後、Shrew VPN接続を追加設定することなく、企業VPNに接続しながらローカルLANにアクセスできました(またはソフトウェア)。


これがAndroidで利用可能であれば、素晴らしいでしょう。
ガブリエルフェア14年

1
私は2019年からです、それは動作します!!!!!!
セルゲイポビセンコ

5

上記のすばらしいハックを提供してくれたSasha Pachevに感謝します。

vpnagentdまた、に加えられた変更を上書きすることにより、リゾルバを台無しにします/etc/resolv.conf。私は最終的にそれに対してレースに勝つことによってそれを解決しました:

#!/bin/bash

dnsfix() {
    [ -f /etc/resolv.conf.vpnbackup ] || echo "Not connected?" >&2 || return 0 # do nothing in case of failure
    while ! diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup #>/dev/null
    do
         cat /etc/resolv.conf.vpnbackup >/etc/resolv.conf
    done
    chattr +i /etc/resolv.conf
    diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null 
}

while ! dnsfix
do
    echo "Retrying..."
    chattr -i /etc/resolv.conf
done

chattr -i /etc/resolv.conf切断するときは忘れないでください。

上記のroutesメソッドのように、コールバックをインターセプトして解決しようとしていますが、対応するコールバックまたはメソッドがまだ見つかりません。

Update1 / 2:APIを使用してリゾルバーファイルの変更を監視してstraceいることvpnagentdが明らかになりましたinotify。そこから先は下り坂でした。追加のハックは次のとおりです。

int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
  return 0;
}

これは、エージェントのすべてのファイル監視を無効にするため、少しやり過ぎです。しかし、うまくいくようです。

以下のvpnクライアントラッパースクリプトは、すべての機能を統合しています(この追加のハックを含むように更新されています)。chattr使用されなくなりました。

更新3:スクリプトのユーザー名/パスワード設定を修正しました。現在、vpn.conf以下で説明する形式(およびルートのみのアクセス許可)のファイルを使用します。

#!/bin/bash

# Change this as needed
CONF="/etc/vpnc/vpn.conf"
# vpn.conf format
#gateway <IP>
#username <username>
#password <password>
#delete_routes <"route spec"...> eg. "default gw 0.0.0.0 dev cscotun0"
#add_routes <"route spec"...> eg. "-net 192.168.10.0 netmask 255.255.255.0 dev cscotun0" "-host 10.10.10.1 dev cscotun0"

ANYCONNECT="/opt/cisco/anyconnect"

usage() {
    echo "Usage: $0 {connect|disconnect|state|stats|hack}"
    exit 1
}

CMD="$1"
[ -z "$CMD" ] && usage

ID=`id -u`

VPNC="$ANYCONNECT/bin/vpn"

dnsfix() {
    [ -f /etc/resolv.conf.vpnbackup ] || echo "Not connected?" >&2 || return 0 # do nothing in case of failure
    while ! diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null
    do
         cat /etc/resolv.conf.vpnbackup >/etc/resolv.conf
    done
#    chattr +i /etc/resolv.conf
    diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null 
}

case "$CMD" in
    "connect")
        [ $ID -ne 0 ] && echo "Needs root." && exit 1
        HOST=`grep ^gateway $CONF | awk '{print $2}'`
        USER=`grep ^user $CONF | awk '{print $2}'`
        PASS=`grep ^password $CONF | awk '{print $2}'`
        OLDIFS=$IFS
        IFS='"'
        DEL_ROUTES=(`sed -n '/^delete_routes/{s/delete_routes[ \t\"]*//;s/\"[ \t]*\"/\"/g;p}' $CONF`)
        ADD_ROUTES=(`sed -n '/^add_routes/{s/add_routes[ \t\"]*//;s/\"[ \t]*\"/\"/g;p}' $CONF`)
        IFS=$OLDIFS

        /usr/bin/expect <<EOF
set vpn_client "$VPNC";
set ip "$HOST";
set user "$USER";
set pass "$PASS";
set timeout 5
spawn \$vpn_client connect \$ip
match_max 100000
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    ">> The VPN client is not connected." { exit 0};
    ">> state: Disconnecting" { exit 0};
    "Connect Anyway?"
}
sleep .1
send -- "y\r"
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    "Username:"
}
sleep .1
send -- "\$user\r"
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    "Password: "
}
send -- "\$pass\r";
expect eof
EOF
        sleep 2
        # iptables
        iptables-save | grep -v DROP | iptables-restore

        # routes
        for ROUTE in "${DEL_ROUTES[@]}"
        do
#            echo route del $ROUTE
            route del $ROUTE
        done
        for ROUTE in "${ADD_ROUTES[@]}"
        do
#            echo route add $ROUTE
            route add $ROUTE
        done

        # dns
        while ! dnsfix
        do
            echo "Try again..."
#            chattr -i /etc/resolv.conf
        done

        echo "done."
        ;;
    "disconnect")
#        [ $ID -ne 0 ] && echo "Needs root." && exit 1
        # dns
#        chattr -i /etc/resolv.conf

        $VPNC disconnect
        ;;
    "state"|"stats")
        $VPNC $CMD
        ;;
    "hack")
        [ $ID -ne 0 ] && echo "Needs root." && exit 1
        /etc/init.d/vpnagentd stop
        sleep 1
        killall -9 vpnagentd 2>/dev/null
        cat - >/tmp/hack.c <<EOF
#include <sys/socket.h>
#include <linux/netlink.h>

int _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv()
{
  int fd=50;          // max fd to try
  char buf[8192];
  struct sockaddr_nl sa;
  socklen_t len = sizeof(sa);

  while (fd) {
     if (!getsockname(fd, (struct sockaddr *)&sa, &len)) {
        if (sa.nl_family == AF_NETLINK) {
           ssize_t n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
        }
     }
     fd--;
  }
  return 0;
}

int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
  return 0;
}
EOF
        gcc -o /tmp/libhack.so -shared -fPIC /tmp/hack.c
        mv /tmp/libhack.so $ANYCONNECT
        sed -i "s+^\([ \t]*\)$ANYCONNECT/bin/vpnagentd+\1LD_PRELOAD=$ANYCONNECT/lib/libhack.so $ANYCONNECT/bin/vpnagentd+" /etc/init.d/vpnagentd
        rm -f /tmp/hack.c
        /etc/init.d/vpnagentd start
        echo "done."
        ;;
    *)
        usage
        ;;
esac

1
あなたの通知ハックは、AnyConnect 3.1.14018のインストールに関する私の新しい(2017-02-25)問題を解決しました。これにより、新しいターミナルウィンドウまたはGNU画面を開くたびに切断されます。何らかの理由で/ var / run / utmpを監視しています。まあ、もうない、ありがとう!
マーティンドレイ

いいね 「過剰」が友達になることもあります。:
マウロレイシー

4

私の会社はまだそのVPNを使用しています。vpncクライアントは単にiptables設定をそのように変更するだけです:

#iptables-save
#2012年6月17日14:12:20にiptables-save v1.4.10で生成
*フィルタ
:入力ドロップ[0:0]
:前方承認[0:0]
:出力ドロップ[0:0]
-A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT 
-A入力-i tun0 -j ACCEPT 
-A INPUT -i lo0 -j ACCEPT
-A入力-jドロップ 
-A出力-s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT 
-A出力-o tun0 -j ACCEPT 
-A出力-o lo0 -j ACCEPT 
-A出力-jドロップ 
コミット

VPNトラフィックを除くすべてをフィルタリングします。

iptables-saveを使用してファイル内のフィルターを取得し、必要に応じてINPUTおよびOUTPOUTアクセス行を追加し、iptables-restoreを使用してファイルを再適用します。

たとえば、192.168.0のローカルネットワークにアクセスする場合

#2012年6月17日14:12:20にiptables-save v1.4.10で生成
*フィルタ
:入力ドロップ[0:0]
:前方承認[0:0]
:出力ドロップ[0:0]
-A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT 
-A INPUT -s 192.168.0.0/24 -d 192.168.0.14/32 -j ACCEPT #local in
-A入力-i tun0 -j ACCEPT 
-A INPUT -i lo0 -j ACCEPT 
-A入力-jドロップ 
-A出力-s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT 
-A出力-s 192.168.0.14/32 -d 192.168.0.0/24 -j ACCEPT #local out
-A出力-o tun0 -j ACCEPT 
-A出力-o lo0 -j ACCEPT 
-A出力-jドロップ 
コミット

2
その間違った、あなたのルートを追加するのは簡単ではない..私は試みたが、それは機能しなかった..あなたを変更させないカーネルルーティングテーブルの制御を取るVPNクライアント
サティッシュ

3

これに関するニュースはありますか?

Cisco VPNクライアントドライバーは、ネットワークスタック内で何を実行して、ローカル管理者がマシンを管理する機能を無効にしますか?

私は完全に同意し、同じことについて疑問に思っていました。

とにかく、それはインストールするために管理者権限を必要とするアプリであり、実行中にあなたがすることを非常にうまくフィルタリングするかもしれません...

Windowsでの私の試みも失敗します:

route change 0.0.0.0 mask 0.0.0.0 192.168.1.1 metric 1
 OK!

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.1.1    192.168.1.230     21 <-- LAN
          0.0.0.0          0.0.0.0    192.168.120.1    192.168.120.3      2 <-- VPN

ハハ。ここでは20未満のメトリックはないようです。


Linuxに関する限り、これ(petefreitag.com/item/753.cfm)は、ファイアウォールも関係していることを示しているようです。
マルキ

2
ShrewSoft VPNを見つけました。Cisco IPSec VPNサーバーに接続でき、自分のネットワークから切断するというVPNサーバー管理者の要求を無視します。(詳細な手順については、superuser.com / questions / 312947 /…を参照してください)この質問には答えていませんが、回避策です。:ShrewSoft VPNはIPSecでのみ機能します。それは、SSL VPN(すなわち新しいシスコのAnyConnect VPNクライアント)では動作しません
イアン・ボイド

3

私はそれを正しく理解しているかどうかわかりませんが、最初に私の理解を明確にします:

ローカルLAN(たとえば、10.0.0.0 / 16、およびリモートCisco VPN Server(たとえば、64.0.0.0 / 16)があります。CiscoVPNクライアントを介してVPNサーバーに接続したいが、まだ必要です。この場合、VPN接続から10.0.xx / 16全体を分離する必要があります。次のルートをMacクライアントに追加する必要があります。

/sbin/route add -net 10.0 -interface en1

ここで、en1は、LANに接続するためのインターフェースです。WindowsとLinuxでも同じものを追加できることを知っています。


3
Macクライアントの場合は+1。私には当てはまりません。そして、このコマンドが動作するかもしれないが、シスコのクライアントがすぐに作成された後、それを削除することがあります(シスコのクライアントが変更ルートから誰を防ぐように見える)
イアン・ボイド

2

コメントを追加できないため、ここに投稿します。Windowsで実行しています。

仮想マシンを使用し、VM内でAnyConnectを実行し、作業環境と会社のネットワーク間のメディエーターとしてVMを使用するソリューションは、「最愛の」IT部門がVPNを介して0.0.0.0をルーティングするため、ローカルネットワーク(これを含む)ローカルPCとVMの間)は、VPN経由でルーティングされます(sic!)。

@Sasha Pachevが投稿したソリューションを適用しようとしましたが、最終的に.dllにパッチを適用して、関数の先頭で0を返すようにしました。最終的には、動的ライブラリとのいくつかの戦いの後、自分のニーズに応じてルーティングテーブルを変更することができましたが、明らかにそれだけでは十分ではありません!

スプリットトンネリングを達成するためのルールは正しいように見えますが、それでも一般的な失敗が発生します。 解決できたのと同様の問題に遭遇しましたか?

  • インターネットへのゲートウェイは192.168.163.2です
  • 会社のネットワークへの私のゲートウェイは10.64.202.1(したがって、全体の10です。*私は「とびさん」として扱うサブネット)

これは私のルーティングテーブルがどのように見えるかです(VPNがオンのときに手動で変更した後)

ここに画像の説明を入力してください

まだpingの結果は次のとおりです

C:\Users\Mike>ping -n 1 10.64.10.11
Reply from 10.64.10.11: bytes=32 time=162ms TTL=127

C:\Users\Mike>ping -n 1 8.8.8.8
PING: transmit failed. General failure.

C:\Users\Mike>ping -n 1 192.168.163.2
General failure.

参考のため、VPNが切断された(変更されていない)場合のルートテーブルの様子を以下に示します。

ここに画像の説明を入力してください

私はpingを実行しようとしているとき、これは、その場合には(未変更)VPNが接続されているときに、テーブルがどのように見えるかである8.8.8.8(会社のファイアウォールは、トラフィックがイントラネットの外に行くことを許可していないので)私は単にタイムアウトを取得します

ここに画像の説明を入力してください


DLLにパッチを適用するのが難しいのですが、誰かがそれらのコピーを提供したり、変更する必要のあるオフセットをもう少し詳しく説明したりできますか?
ショーンC

1

Cisco AnyConnect SSL VPNを使用する際にルーティングテーブルの制御を維持したい場合は、OpenConnectをご覧ください。どちらもCisco AnyConnect SSL VPNをサポートし、ルーティングテーブルエントリを中断または「保護」しようとしません。@Vadzimは、上記コメントでこれを暗示しています。

AnyConnect Secure Mobility Clientにパッチを適用する以外のすべてを試した後、WindowsでOpenConnect GUIを使用して正常に置き換えることができました。これにより、ローカルリソースへの接続を維持できました(そしてルーティングテーブルを更新しました)。

私はWindowsでOpenConnectを使用していますが、プロジェクトページによれば、Linux、BSD、およびmacOS(他のプラットフォームの中でも)もサポートしています


1
これは私のために働いた。しかし、私の組織はトークンを使用しているため、パスワードは毎回異なります。そのため、「バッチモード」をオフにする必要がありました。そうしないと、最初のパスワードが保存されて再利用されます。
ガブリエルルシ

0

ゲートウェイでこれらのエントリを削除してみてください。pingが機能する10.64.202.13かどうかを確認し、8.8.8.8それらを1つずつ追加して、どのエントリが問題の原因であるかを特定してください。

DLLにどのようにパッチを適用しましたか。0.0.0.0VPNゲートウェイを追加し続けるため、ルーティングテーブルを変更することさえできません。


1
質問の説明や追加情報が必要な場合は、回答に含めるのではなく、コメントを投稿してください。ありがとう。
マシューウィリアムズ

既存の質問にコメントを追加できませんでした。
トニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.