IPv6サブネットからIPv4インターネットへCloudflare WARPでアクセスしてみた
こんにちは。CX事業本部製造ビジネステクノロジー部のakkyです。
今月からAWSでIPv4アドレスが有料化され、まもなく1カ月が経とうとしています。これによってIPv4アドレス1つあたり月おおよそ3.6ドルの料金がかかるようになりました。(ただし、月あたり750時間(およそ1カ月ぶん)の無料枠があります)
最近はIPv6対応のISPも多いですし、内部で使用するAPIなどはIPv6だけでも成り立つかもしれませんが、 自分からアクセスする外部のサーバがIPv4のみの提供だと、結局自分のサーバにもIPv4アドレスを付けたり、NATゲートウェイを有効にしてDNS64/NAT64を利用する必要が出てきます。
また、AWS自体のサービスもすべてがIPv6対応しているわけではなく、IPv4のみ提供しているエンドポイントも多いのが現状です。
このような状況のため、しばらくはIPv4アドレスが必要な状況は続きますが、検証用の環境からIPv4アクセスしたいとき、若干の手間にはある程度目をつぶれる場合にコストを削減できないものでしょうか?
Cloudflare WARP
Cloudflare WARPはCloudflareが提供するセキュア接続のためのVPNサービスです。
WARPを使用すると、CloudflareへWireguardトンネルを張り、Cloudflareのエッジからインターネットに接続するようになります。 WARPのサーバへはIPv6のみで接続できるうえ、IPv4サイトへもアクセスできるようになります。
今回はCloudflare WARPを利用してIPv6サブネットに建てたEC2インスタンスからIPv4アクセスする方法を試してみました。
VPCの設定
原理上、WARPを使えばIPv6アドレスのみのインスタンスからIPv4インターネットへ出られるのですが、EC2 Instance Connectを利用して管理したいので、IPv4/v6デュアルスタックのサブネットを使います。もちろんグローバルIPv4アドレスは使用しません。
IPv6でインターネットに出るには「Egress Only インターネットゲートウェイ」が必須です。利用料は無料です。
今回はCDKで用意しました。ipProtocol: ec2.IpProtocol.DUAL_STACK
と指定すればOKです。
import * as cdk from "aws-cdk-lib"; import * as ec2 from "aws-cdk-lib/aws-ec2"; import { Construct } from "constructs"; export class Ipv6VpcStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, "ipv6vpc", { maxAzs: 1, natGateways: 0, ipProtocol: ec2.IpProtocol.DUAL_STACK, subnetConfiguration: [ { cidrMask: 24, name: "PublicSubnet1", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "PrivateSubnet1", subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, }, ], }); const ec2sg = new ec2.SecurityGroup(this, "ec2-sg", { vpc, }); const eicsg = new ec2.SecurityGroup(this, "eic-sg", { vpc, allowAllOutbound: false, }); ec2sg.addIngressRule(eicsg, ec2.Port.tcp(22)); eicsg.addEgressRule(ec2sg, ec2.Port.tcp(22)); new ec2.CfnInstanceConnectEndpoint(this, "eice", { subnetId: vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }).subnetIds[0], securityGroupIds: [eicsg.securityGroupId], }); const internetsg = new ec2.SecurityGroup(this, "outband", { vpc, allowAllIpv6Outbound: true, }); const server = new ec2.Instance(this, "ipv6server", { vpc: vpc, vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }, instanceType: ec2.InstanceType.of( ec2.InstanceClass.T3, ec2.InstanceSize.MICRO ), machineImage: ec2.MachineImage.latestAmazonLinux2023({ cpuType: ec2.AmazonLinuxCpuType.X86_64, }), }); server.addSecurityGroup(ec2sg); server.addSecurityGroup(internetsg); } }
EC2インスタンスにつけるセキュリティグループにallowAllIpv6Outbound: true
がないとIPv6でインターネットに出られません。IPv4はデフォルトでアウトバンドが全許可されているものの、IPv6は全拒否となっているためです。
起動直後の状況
上記CDKスタックで作成したEC2インスタンスはプライベートIPv4アドレスとIPv6グローバルユニキャストアドレスを持っているので、IPv6サーバにはアクセスできますが、IPv4サーバへは通信できません。
IPv6✅
[ec2-user@ip-10-0-1-112 ~]$ ping google.com PING google.com(nrt20s21-in-x0e.1e100.net (2404:6800:4004:81f::200e)) 56 data bytes 64 bytes from nrt20s21-in-x0e.1e100.net (2404:6800:4004:81f::200e): icmp_seq=1 ttl=115 time=2.07 ms 64 bytes from nrt20s21-in-x0e.1e100.net (2404:6800:4004:81f::200e): icmp_seq=2 ttl=115 time=2.15 ms 64 bytes from nrt20s21-in-x0e.1e100.net (2404:6800:4004:81f::200e): icmp_seq=3 ttl=115 time=2.05 ms 64 bytes from nrt20s21-in-x0e.1e100.net (2404:6800:4004:81f::200e): icmp_seq=4 ttl=115 time=2.10 ms ^C --- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 2.045/2.090/2.150/0.038 ms
IPv4❌
[ec2-user@ip-10-0-1-112 ~]$ ping ipv4.google.com PING ipv4.l.google.com (142.251.222.14) 56(84) bytes of data. ^C --- ipv4.l.google.com ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1080ms
Cloudflare WARPのインストール
こちらのページを参考にwarp-cliをインストールします。
Amazon Linux2023を使用したので、RHELを参考に以下のようにしました。
curl -fsSl https://pkg.cloudflareclient.com/cloudflare-warp-ascii.repo | sudo tee /etc/yum.repos.d/cloudflare-warp.repo sudo dnf update sudo dnf install cloudflare-warp
Warpに接続します。本来はregister→connectの順番ですが、興味本位で順番を逆にしたところNICがない状態で作られてしまいました。
$ warp-cli connect NOTICE: Cloudflare only collects limited DNS query and traffic data (excluding payload) that is sent to our network when you have the app enabled on your device. We will not sell, rent, share, or otherwise disclose your personal information to anyone, except as otherwise described in this Policy, without first providing you with notice and the opportunity to consent. All information is handled in accordance with our Privacy Policy. More information is available at: - https://www.cloudflare.com/application/terms/ - https://www.cloudflare.com/application/privacypolicy/ Accept Terms of Service and Privacy Policy? [y/N] y Success
registerするとNICが作られました。
$ warp-cli register Warning: The "register" command will be deprecated in a future release. Please use "registration new" instead Success
本来は、以下のコマンドでいいはずです。
warp-cli registration new warp-cli connect
connectした状態で、IPv4インターネットへアクセスできるようになりました。
$ ping ipv4.google.com PING ipv4.l.google.com (142.251.42.142) 56(84) bytes of data. 64 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=1 ttl=118 time=2.88 ms 64 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=2 ttl=118 time=2.39 ms 64 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=3 ttl=118 time=2.30 ms 64 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=4 ttl=118 time=2.32 ms ^C --- ipv4.l.google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 2.304/2.472/2.877/0.236 ms
以上