AWS之S3套CloudFront的CDN

问题

需要给S3访问套一层CDN,AWS的CDN是CloudFront。

解决

主要步骤

  • 创建公私钥密钥对
  • 创建配置密钥组
  • 创建CloudFront分配
  • 测试(Java签名URL)

创建公私钥密钥对

生成私钥文件
openssl genrsa -out private_key.pem 2048

使用openssl命令生成私钥文件:private_key.pem

生成公钥文件
openssl rsa -pubout -in private_key.pem -out public_key.pem

通过私钥文件生成公钥文件:public_key.pem。这个文件需要在AWS平台中进行配置。

AWS平台设置公钥

AWS平台设置密钥
通过如果页面设置公钥,其中密钥值内容,通过如下命令获得:

cat public_key.pem
生成Java调用的der文件
openssl pkcs8 -topk8 -nocrypt -in private_key.pem -inform PEM -out private_key.der -outform DER

通过私钥文件生成der格式的私钥文件是为了方便Java程序进行开发。

创建配置密钥组

添加密钥组
添加密钥到密钥组
这里就将公钥设置到密钥组了。

创建CloudFront分配

创建CloudFront
开始创建CloudFront分配页面,继续:
分配设置
源域名就是选择一个s3桶即可;这里重点主要是【限制存储访问】设置,这个设置主要是让CloudFront创建一个有权限访问对应到s3桶的身份,并将这个身份权限同步到s3的权限中。
设置URL签名
这里主要给CloudFront的分配者设置公钥密钥组,主要就是为了使用CloudFront的CDN客户端访问CDN的时候需要使用私钥签名的URL才能正常访问CDN中的文件。

测试(Java签名URL)

Gradle依赖
    compile group: 'org.bouncycastle', name:'bcprov-jdk15to18', version:'1.68'
    compile group: 'net.java.dev.jets3t', name:'jets3t', version:'0.9.4'
    compile group: 'com.amazonaws', name:'aws-java-sdk-s3', version:'1.11.993'
Java
package com.zyl.java;


import com.amazonaws.services.s3.internal.ServiceUtils;
import com.amazonaws.util.IOUtils;
import org.jets3t.service.CloudFrontService;
import org.jets3t.service.CloudFrontServiceException;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.Security;

public class Main {
  public static void main(String[] args) throws IOException, CloudFrontServiceException {
// Signed URLs for a private distribution
// Note that Java only supports SSL certificates in DER format,
// so you will need to convert your PEM-formatted file to DER format.
// To do this, you can use openssl:
// openssl pkcs8 -topk8 -nocrypt -in origin.pem -inform PEM -out new.der
//    -outform DER
// So the encoder works correctly, you should also add the bouncy castle jar
// to your project and then add the provider.

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    // CDN地址
    String distributionDomain = "xxxxx.cloudfront.net";
    // 私钥文件
    String privateKeyFilePath = "/Users/zhangyalin/Downloads/private_key.der";
    // key
    String s3ObjectKey = "Exampl中文.txt";

    // 中文URL处理
    char[] chars = s3ObjectKey.toCharArray();
    StringBuilder stringBuilder = new StringBuilder();
    for (char c : chars){
      if (Character.isIdeographic(c)){
        stringBuilder.append(URLEncoder.encode(String.valueOf(c), StandardCharsets.UTF_8.toString()));
      } else {
        stringBuilder.append(c);
      }
    }

    s3ObjectKey = stringBuilder.toString();

    String policyResourcePath = "https://" + distributionDomain + "/" + s3ObjectKey;

    // AWS平台配置的公钥ID
    String keyPairId = "xxxxx";

// Convert your DER file into a byte array.

    byte[] derPrivateKey = IOUtils.toByteArray(new
            FileInputStream(privateKeyFilePath));

// Generate a "canned" signed URL to allow access to a
// specific distribution and file

    String signedUrlCanned = CloudFrontService.signUrlCanned(
            policyResourcePath, // Resource URL or Path
            keyPairId,     // Certificate identifier,
            // an active trusted signer for the distribution
            derPrivateKey, // DER Private key data
            ServiceUtils.parseIso8601Date("2021-04-07T14:20:00.000Z") // DateLessThan
    );
    System.out.println(signedUrlCanned);

// Build a policy document to define custom restrictions for a signed URL.

    String policy = CloudFrontService.buildPolicyForSignedUrl(
            // Resource path (optional, can include '*' and '?' wildcards)
            policyResourcePath,
            // DateLessThan
            ServiceUtils.parseIso8601Date("2021-11-14T22:20:00.000Z"),
            // CIDR IP address restriction (optional, 0.0.0.0/0 means everyone)
            "0.0.0.0/0",
            // DateGreaterThan (optional)
            ServiceUtils.parseIso8601Date("2011-10-16T06:31:56.000Z")
    );

// Generate a signed URL using a custom policy document.

    String signedUrl = CloudFrontService.signUrl(
            // Resource URL or Path
            policyResourcePath,
            // Certificate identifier, an active trusted signer for the distribution
            keyPairId,
            // DER Private key data
            derPrivateKey,
            // Access control policy
            policy
    );
    System.out.println(signedUrl);
  }
}

然后控制URL签名的过期日期,运行后,得到两个URL,直接在浏览器打开这个URL即可。

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值