Providing secure access to content in Cloud CDN
- Prepare your cloud
- Create a VM with a web server
- Create and configure a public DNS zone
- Add a TLS certificate to Yandex Certificate Manager
- Prepare a source bucket for the CDN resource .
- Create a CDN resource
- Create a CNAME resource record for the CDN resource
- Publish the webiste on the web server
- Test secure access to files
- How to delete the resources you created
In this tutorial, you will create a website to generate signed links with a secure token to a CDN resource in Cloud CDN. The referenced content will be available only for five minutes from the time the link was received and only to the user the link was generated for.
The website will be deployed on a VM created from a public LAMP image with a pre-installed Apache HTTP server
To configure secure access to content in Cloud CDN:
- Prepare your cloud.
- Create a VM with a web server.
- Create and configure a public DNS zone.
- Add a TLS certificate to Yandex Certificate Manager.
- Prepare a source bucket for the CDN resource.
- Create a CDN resource.
- Create a CNAME resource record for the CDN resource.
- Publish the webiste on the web server..
- Test secure access to files.
If you no longer need the resources you created, delete them.
Prepare your cloud
Sign up for Yandex Cloud and create a billing account:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Required paid resources
The support cost includes:
- Fee for using a public IP address (see Yandex Virtual Private Cloud pricing).
- Fee for VM computing resources and disks (see Yandex Compute Cloud pricing).
- Fee for using a public DNS zone and public DNS requests (see Yandex Cloud DNS pricing).
- Fee for data storage in Object Storage, operations with data, and outgoing traffic (see Object Storage pricing).
- Fee for outgoing traffic from CDN servers (see Cloud CDN pricing).
Create a cloud network and subnet
- In the management console
, select the folder to create your resources in. - In the list of services, select Virtual Private Cloud.
- At the top right, click Create network.
- In the Name field, specify
webserver-network
. - In the Advanced field, disable the Create subnets option.
- Click Create network.
- In the left-hand panel, select
Subnets. - At the top right, click Create subnet.
- In the Name field, specify
webserver-subnet-ru-central1-b
. - In the Zone field, select the
ru-central1-b
availability zone. - In the Network field, select the
webserver-network
cloud network. - In the CIDR field, specify
192.168.1.0/24
. - Click Create subnet.
-
Create a network named
webserver-network
:yc vpc network create webserver-network
Result:
id: enp1gg8kr3pv******** folder_id: b1gt6g8ht345******** created_at: "2023-12-20T20:08:11Z" name: webserver-network default_security_group_id: enppne4l2eg5********
For more information about the
yc vpc network create
command, see the CLI reference. -
Create a subnet in the
ru-central1-b
availability zone:yc vpc subnet create webserver-subnet-ru-central1-b \ --zone ru-central1-b \ --network-name webserver-network \ --range 192.168.1.0/24
Result:
id: e2li9tcgi7ii******** folder_id: b1gt6g8ht345******** created_at: "2023-12-20T20:11:16Z" name: webserver-subnet-ru-central1-b network_id: enp1gg8kr3pv******** zone_id: ru-central1-b v4_cidr_blocks: - 192.168.1.0/24
For more information about the
yc vpc subnet create
command, see the CLI reference.
-
To create a network, use the create REST API method for the Network resource or the NetworkService/Create gRPC API call.
-
To create a subnet, use the create REST API method for the Subnet resource or the SubnetService/Create gRPC API call.
Create a security group
Create a security group that allows inbound TCP traffic on ports 22
, 80
, and 443
as well as any outbound traffic.
-
In the management console
, select the folder to create your resources in. -
In the list of services, select Virtual Private Cloud.
-
In the left-hand panel, select
Security groups. -
Click Create security group.
-
In the Name field, specify the name:
webserver-sg
. -
In the Network field, select the
webserver-network
network you created earlier. -
Under Rules, create the following traffic management rules:
Traffic
directionDescription Port range Protocol Source /
Destination nameCIDR blocks Incoming http
80
TCP
CIDR
0.0.0.0/0
Incoming https
443
TCP
CIDR
0.0.0.0/0
Incoming ssh
22
TCP
CIDR
0.0.0.0/0
Outgoing any
All
Any
CIDR
0.0.0.0/0
-
Click Save.
Run this command:
yc vpc security-group create \
--name webserver-sg \
--rule "description=http,direction=ingress,port=80,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \
--rule "description=https,direction=ingress,port=443,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \
--rule "description=ssh,direction=ingress,port=22,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \
--rule "description=any,direction=egress,port=any,protocol=any,v4-cidrs=[0.0.0.0/0]" \
--network-name webserver-network
Result:
id: enp4htsnl1sa********
folder_id: b1gt6g8ht345********
created_at: "2023-12-23T19:07:03Z"
name: webserver-sg
network_id: enp37qpnksl2********
status: ACTIVE
rules:
- id: enpdu0t8san9********
description: http
direction: INGRESS
ports:
from_port: "80"
to_port: "80"
protocol_name: TCP
protocol_number: "6"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
- id: enpr7oirpff5********
description: https
direction: INGRESS
ports:
from_port: "443"
to_port: "443"
protocol_name: TCP
protocol_number: "6"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
- id: enp0bgk6dkdd********
description: ssh
direction: INGRESS
ports:
from_port: "22"
to_port: "22"
protocol_name: TCP
protocol_number: "6"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
- id: enpspns0tfml********
description: any
direction: EGRESS
protocol_name: ANY
protocol_number: "-1"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
For more information about the yc vpc security-group create
command, see the CLI reference.
Save the obtained security group ID (id
): you will need it to create a VM.
To create a security group, use the create REST API method for the SecurityGroup resource or the SecurityGroupService/Create gRPC API call.
Prepare files for uploading to the bucket
-
Save any image in JPEG format to the
content.jpg
file. -
Create a file named
index.html
:<html> <body> </body> </html>
Create a VM with a web server
Before you start, prepare a key pair (public and private keys) to access your VM over SSH.
-
In the management console
, select the folder to create your resources in. -
In the list of services, select Compute Cloud.
-
In the left-hand panel, select
Virtual machines. -
Click Create virtual machine.
-
Under General information:
- In the Name field, specify the name:
mywebserver
. - In the Availability zone field, select
ru-central1-b
.
- In the Name field, specify the name:
-
Under Boot disk image, go to the Marketplace tab and click Show all Marketplace products.
-
In the window that opens, find and select LAMP.
-
Under Network settings:
- In the Subnet field, select the
webserver-subnet-ru-central1-b
subnet you created earlier. - In the Public IP field, select
Auto
. - In the Security groups field, select the
webserver-sg
security group you created earlier.
- In the Subnet field, select the
-
Under Access, specify the information required to access the VM:
- Enter the username in the Login field:
yc-user
. - In the SSH key field, paste the contents of the public key created earlier.
- Enter the username in the Login field:
-
Click Create VM.
Run this command:
yc compute instance create \
--name mywebserver \
--zone ru-central1-b \
--network-interface subnet-name=webserver-subnet-ru-central1-b,nat-ip-version=ipv4,security-group-ids=<security_group_ID> \
--create-boot-disk image-folder-id=standard-images,image-id=fd8jtn9i7e9ha5q25niu \
--ssh-key ~/.ssh/id_ed25519.pub
Where:
<security_group_ID>
: Previously saved security group ID.--ssh-key
: Path to the file with the public SSH key. e.g.,~/.ssh/id_ed25519.pub
.
Result:
done (32s)
id: fhmaq4shfrcm********
folder_id: b1gt6g8ht345********
created_at: "2023-12-23T05:36:34Z"
name: mywebserver
zone_id: ru-central1-b
platform_id: standard-v2
resources:
memory: "2147483648"
cores: "2"
core_fraction: "100"
status: RUNNING
metadata_options:
gce_http_endpoint: ENABLED
aws_v1_http_endpoint: ENABLED
gce_http_token: ENABLED
aws_v1_http_token: DISABLED
boot_disk:
mode: READ_WRITE
device_name: fhmprher1d0q********
auto_delete: true
disk_id: fhmprher1d0q********
network_interfaces:
- index: "0"
mac_address: d0:0d:ad:13:91:7e
subnet_id: e9bk1m87r4m4********
primary_v4_address:
address: 192.168.1.11
one_to_one_nat:
address: 158.160.***.***
ip_version: IPV4
security_group_ids:
- enpa5j0mrgm4********
gpu_settings: {}
fqdn: fhmaq4shfrcm********.auto.internal
scheduling_policy: {}
network_settings:
type: STANDARD
placement_policy: {}
For more information about the yc compute instance create
command, see the CLI reference.
To create a VM, use the create REST API method for the Instance resource or the InstanceService/Create gRPC API call.
This will create the mywebserver
VM in your folder. To connect to the VM over SSH, use the yc-user
username and the VM’s public IP address. If you plan to use the created web server over a long period of time, make this VM's public IP address static.
Create and configure a public DNS zone
-
Create a public DNS zone in Yandex Cloud DNS.
Management consoleYandex Cloud CLIAPI-
In the management console
, select the folder to create your resources in. -
Select Cloud DNS.
-
Click Create zone.
-
Specify the zone settings consistent with your domain:
- Zone: Domain zone. The zone name must end with a period. For example, the
example.com.
zone name corresponds to theexample.com
domain. To create a domain zone with non-Latin characters, use the Punycode encoding. - Type:
Public
- Name:
my-domain-zone
- Zone: Domain zone. The zone name must end with a period. For example, the
-
Click Create.
Run this command:
yc dns zone create \ --name my-domain-zone \ --zone <domain_name> \ --public-visibility
Where
--zone
is your domain name, e.g.,example.com.
. The--zone
parameter value must end with a period. For example, theexample.com.
zone name corresponds to theexample.com
domain.Result:
id: dns39gihj0ef******** folder_id: b1gt6g8ht345******** created_at: "2023-12-21T16:43:37.883Z" name: my-domain-zone zone: example.com. public_visibility: {}
For more information about the
yc dns zone create
command, see the CLI reference.To create a public DNS zone, use the create REST API method for the DnsZone resource or the DnsZoneService/Create gRPC API call.
-
-
Delegate your domain to Cloud DNS. To do this, in your domain registrar's account, specify the addresses of these DNS servers in your domain settings:
ns1.yandexcloud.net
andns2.yandexcloud.net
. -
In your DNS zone, create an A resource record pointing to the public IP address of the previously created VM with a web server:
Management consoleYandex Cloud CLIAPI-
In the management console
, select the folder to create your resources in. -
Select Cloud DNS.
-
Select the previously created DNS zone.
-
Click Create record.
-
Set the record parameters:
-
In the Name field, select
Matches zone name (@)
. -
In the Type field, select
A
as the record type. -
In the Data field, specify the public IP address of the previously created VM with a web server.
You can find the VM IP address in the Network section on the VM page in the management console
or using this CLI command:yc compute instance get mywebserver
.
-
-
Click Create.
Run this command:
yc dns zone add-records \ --name my-domain-zone \ --record "@ 600 A <VM_IP_address>"
Where
<VM_IP_address>
is the public IP address of the previously created VM with a web server.You can find the VM IP address in the Network section on the VM page in the management console
or using this CLI command:yc compute instance get mywebserver
.Result:
+--------+--------------+------+---------------+-----+ | ACTION | NAME | TYPE | DATA | TTL | +--------+--------------+------+---------------+-----+ | + | example.com. | A | 51.250.**.*** | 600 | +--------+--------------+------+---------------+-----+
For more information about the
yc dns zone add-records
command, see the CLI reference.To create a resource record in a DNS zone, use the updateRecordSets REST API method for the DnsZone resource or the DnsZoneService/UpdateRecordSets gRPC API call.
-
Add a TLS certificate to Yandex Certificate Manager
-
Add a Let's Encrypt® certificate to Certificate Manager for your domains that the web server and CDN resource will use.
Management consoleYandex Cloud CLIAPI-
In the management console
, select the folder to create your resources in. -
In the list of services, select Certificate Manager.
-
Click Add certificate and select Let's Encrypt certificate.
-
In the window that opens, specify
mymanagedcert
in the Name field. -
In the Domains field, specify your domain name, e.g.,
example.com
.In the same field, in a new line, specify the name of the subdomain to be used for the CDN resource, e.g.,
cdn.example.com
. -
Select the permission check type for the
DNS
domain. -
Click Create.
Run this command:
yc certificate-manager certificate request \ --name mymanagedcert \ --challenge dns \ --domains <domain_name>,<subdomain_name>
Where:
<domain_name>
: Name of your domain for the web server, e.g.,example.com
.<subdomain_name>
: Name of the subdomain that the CDN resource will use, e.g.,cdn.example.com
.
Result:
id: fpqbs12t6ion******** folder_id: b1gt6g8ht345******** created_at: "2023-12-24T14:36:39.299844798Z" name: mymanagedcert type: MANAGED domains: - example.com - cdn.example.com status: VALIDATING updated_at: "2023-12-24T14:36:39.299844798Z"
For more information about the
yc certificate-manager certificate request
command, see the CLI reference.Save the ID (
id
) of the created certificate as you will need it when creating a CDN resource.To add a certificate, use the requestNew REST API method for the Certificate resource or the CertificateService/RequestNew gRPC API call.
The new certificate will appear in the certificate list with the
Validating
status. This status means that a Let's Encrypt® certificate was requested and you need to pass a domain permission check for it to be successfully processed. -
-
To successfully issue the certificate, pass the domain permission check:
Management consoleYandex Cloud CLIAPI- In the management console
, select the folder to create your resources in. - In the list of services, select Certificate Manager.
- In the list of certificates, select
mymanagedcert
. - In the window that opens, under Check rights for domains, select
CNAME record
. - In the section of the first domain, click Create record and then click Create in the window that opens.
- Repeat the above action for the second domain.
The domain permission check may take from a few minutes to a few days. Wait until it is complete. As the result, the certificate will be issued and get the
Issued
status.-
Get values of the resource records required for passing the check:
yc certificate-manager certificate get \ --name mymanagedcert \ --full
Result:
id: fpq2gpi42teg******** folder_id: b1gt6g8ht345******** created_at: "2023-12-24T18:13:45.960Z" name: mymanagedcert type: MANAGED domains: - example.com - cdn.example.com status: VALIDATING updated_at: "2023-12-24T18:13:45.960Z" challenges: - domain: cdn.example.com type: DNS created_at: "2023-12-24T18:13:45.960Z" updated_at: "2023-12-24T18:13:49.280Z" status: PENDING message: Create a record in your DNS provider. dns_challenge: name: _acme-challenge.cdn.example.com. type: CNAME value: fpq2gpi42teg********.cm.yandexcloud.net. - domain: cdn.example.com type: DNS created_at: "2023-12-24T18:13:45.960Z" updated_at: "2023-12-24T18:13:49.280Z" status: PENDING message: Create a record in your DNS provider. dns_challenge: name: _acme-challenge.cdn.example.com. type: TXT value: d9RzZH8WZucSY8mXs9cEg1wNteaaNqbxZK7******** - domain: example.com type: DNS created_at: "2023-12-24T18:13:45.960Z" updated_at: "2023-12-24T18:13:49.280Z" status: PENDING message: Create a record in your DNS provider. dns_challenge: name: _acme-challenge.example.com type: CNAME value: fpq2gpi42teg********.cm.yandexcloud.net. - domain: example.com type: DNS created_at: "2023-12-24T18:13:45.960Z" updated_at: "2023-12-24T18:13:49.280Z" status: PENDING message: Create a record in your DNS provider. dns_challenge: name: _acme-challenge.example.com. type: TXT value: iiyJJJlsaFIqQ7DMUzira0OKU3iXuaqiN7U********
For more information about the
yc certificate-manager certificate get
command, see the CLI reference.Save the values of the
value
fields from theCNAME
-type sections underchallenges.dns_challenge
for both domain names. You will need them in the next step. -
Create CNAME resource records to pass the domain permission check:
yc dns zone add-records \ --name my-domain-zone \ --record "_acme-challenge 600 CNAME <dns_challenge_value>" \ --record "_acme-challenge.<subdomain> 600 CNAME <dns_challenge_value>"
Where:
<dns_challenge_value>
: Value saved in the previous step that is required to check you rights to the relevant domain using a CNAME record.<subdomain>
: Name you gave to the CDN resource subdomain, e.g.,cdn
. In this case, the record will look as follows:_acme-challenge.cdn 600 CNAME fpq2gpi42teg********.cm.yandexcloud.net.
.
Result:
+--------+----------------------------------+-------+------------------------------------------+-----+ | ACTION | NAME | TYPE | DATA | TTL | +--------+----------------------------------+-------+------------------------------------------+-----+ | + | _acme-challenge.cdn.example.com. | CNAME | fpq2gpi42teg********.cm.yandexcloud.net. | 600 | | + | _acme-challenge.example.com. | CNAME | fpq2gpi42teg********.cm.yandexcloud.net. | 600 | +--------+----------------------------------+-------+------------------------------------------+-----+
For more information about the
yc dns zone add-records
command, see the CLI reference.The domain permission check may take from a few minutes to a few days. Wait until it is complete. As the result, the certificate will be issued and get the
Issued
status. -
Make sure that the certificate status has changed to
Issued
:yc certificate-manager certificate get \ --name mymanagedcert
Result:
id: fpqr2j0sdb1n******** folder_id: b1gt6g8ht345******** created_at: "2023-12-24T16:38:02.206Z" name: mymanagedcert type: MANAGED domains: - cdn.example.com - example.com status: ISSUED issuer: CN=R3,O=Let's Encrypt,C=US subject: CN=cdn.example.com serial: 4b7d7f0968097ae1a7707854a80******** updated_at: "2023-12-24T16:46:03.578Z" issued_at: "2023-12-24T16:46:03.578Z" not_after: "2024-03-23T15:44:59Z" not_before: "2023-12-24T15:45:00Z"
To get the information required to pass the permission check for a domain, use the get REST API method for the Certificate resource or the CertificateService/Get gRPC API call with the
view=FULL
flag.To create a CNAME resource record in a DNS zone, use the updateRecordSets REST API method for the DnsZone resource or the DnsZoneService/UpdateRecordSets gRPC API call.
Note
For a successful DNS domain rights check based on a
CNAME
record, make sure the_acme-challenge
subdomain of the domain name you are checking has no resource records created, exceptCNAME
. For example, for the_acme-challenge.example.com.
domain name there should only be a CNAME record and no TXT record. - In the management console
Prepare a source bucket for the CDN resource .
-
Create an Object Storage bucket to be used as a source for the CDN resource. The bucket name must be unique.
Management consoleYandex Cloud CLIAWS CLIAPI- In the management console
, select the folder to create your resources in. - In the list of services, select Object Storage.
- At the top right, click Create bucket.
- In the ** Name** field, enter a name for the bucket, e.g.,
cdn-source-bucket
. - In the Max size field, specify
1 GB
. - In the Object read access and Object listing access fields, select
Public
. - Click Create bucket.
- On the page with a list of buckets, select the bucket you created.
- In the left-hand panel, select Settings.
- On the Website tab:
- Select
Hosting
. - In the Home page field, specify
index.html
.
- Select
- Click Save.
-
Create a bucket:
yc storage bucket create \ --name <bucket_name> \ --default-storage-class standard \ --max-size 1073741824 \ --public-read \ --public-list
Where
--name
is the bucket name, unique throughout Object Storage, e.g.,cdn-source-bucket
.Result:
name: cdn-source-bucket folder_id: b1gt6g8ht345******** anonymous_access_flags: read: false list: false default_storage_class: STANDARD versioning: VERSIONING_DISABLED max_size: "1073741824" acl: {} created_at: "2023-12-22T18:11:23.028836Z"
For more information about the
yc storage bucket create
command, see the CLI reference. -
Enable static website hosting in the bucket:
yc storage bucket update \ --name <bucket_name> \ --website-settings '{"index": "index.html"}'
Result:
name: cdn-source-bucket folder_id: b1gt6g8ht345******** default_storage_class: STANDARD versioning: VERSIONING_DISABLED max_size: "1073741824" acl: {} created_at: "2023-12-23T09:56:58.249721Z" website_settings: redirect_all_requests: {}
For more information about the
yc storage bucket update
command, see the CLI reference.
If you do not have the AWS CLI yet, install and configure it.
Assign the
storage.editor
role to the service account used by the AWS CLI.-
Create a bucket:
aws s3api create-bucket \ --endpoint-url https://storage.yandexcloud.net \ --bucket <bucket_name> \ --acl public-read
Where
--bucket
is the bucket name, unique throughout Object Storage, e.g.,cdn-source-bucket
.Result:
{ "Location": "/cdn-source-bucket" }
-
Enable static website hosting in the bucket:
aws --endpoint-url https://storage.yandexcloud.net \ s3 website "s3://<bucket_name>" \ --index-document index.html
Where
<bucket_name>
is the name of the previously created bucket, e.g.,cdn-source-bucket
.
To create a bucket, use the create REST API method for the Bucket resource, the BucketService/Create gRPC API call, or the create S3 API method.
To enable static website hosting in the bucket, use the update REST API method for the Bucket resource, the BucketService/Update gRPC API call, or the upload S3 API method.
- In the management console
-
Upload the prepared files to the bucket:
Management consoleAWS CLIAPI- In the management console
, select the folder to create your resources in. - In the list of services, select Object Storage.
- Select the bucket you created ealier.
- In the top-right corner, click
Upload and select the files you created:index.html
andcontent.jpg
. - In the window that opens, confirm the upload of the objects.
-
Upload the
index.html
file to the bucket:aws --endpoint-url https://storage.yandexcloud.net \ s3 cp ./index.html s3://<bucket_name>/index.html
Where
<bucket_name>
is the name of the previously created bucket, e.g.,cdn-source-bucket
.Result:
upload: ./index.html to s3://cdn-source-bucket/index.html
-
Upload the
content.jpg
file to the bucket:aws --endpoint-url https://storage.yandexcloud.net \ s3 cp ./content.jpg s3://<bucket_name>/content.jpg
Result:
upload: ./content.jpg to s3://cdn-source-bucket/content.jpg
To upload files to the bucket, use the upload S3 API method.
- In the management console
Create a CDN resource
-
In the management console
, select the folder to create your resources in. -
Select Cloud CDN.
-
If the CDN provider is not activated yet, click Activate provider. A connection will be established automatically.
If you do not see the Activate provider button and you can create resources and origin groups, it means that the provider is already activated. Proceed to the next step.
-
Click Create resource.
-
Under Content, specify:
- Content query:
From one origin
. - Origin type:
Server
. - In the Origin domain name field, specify
<bucket_name>.website.yandexcloud.net
, where<bucket_name>
is the name of the previously created bucket used by the CDN resource as a source.
- Content query:
-
Under Domain names for content distribution, in the Domain name field, specify the domain name you intend to assign to your CDN resource, e.g.,
cdn.example.com
.At the bottom of Domain names for content distribution, the CNAME record value will appear. Copy this value as you will need it when creating a CNAME record for the CDN resource.
-
Under Additional:
- In the Origin request protocol field, select
Match client
. - In the Redirect clients field, select
Don't use
. - In the Certificate type field, select
Certificate from Certificate Manager
and then select the previously createdmymanagedcert
certificate from the list that opens. - In the Host header field, select
Custom
. Then, in the Header value field that opens, specify<bucket_name>.website.yandexcloud.net
, where<bucket_name>
is the name of the previously created bucket used by the CDN resource as a source. - Enable Access via secure token.
- In the Secret key that appears, specify a secret key, a string of 6 to 32 characters. It will be transmitted to the CDN resource configuration and used to generate and check signed links.
- In the Limit access by IP address field, select
Only trusted IP addresses
.
- In the Origin request protocol field, select
-
Click Create.
-
If it is the first CDN resource you are creating, connect to the provider first:
yc cdn provider activate \ --type gcore
For more information about the
yc cdn provider activate
command, see the CLI reference. -
Create a resource:
yc cdn resource create <subdomain_name> \ --origin-custom-source <bucket_name>.website.yandexcloud.net \ --origin-protocol 'match' \ --cert-manager-ssl-cert-id <certificate_ID> \ --host-header <bucket_name>.website.yandexcloud.net \ --secure-key <secret_key> \ --enable-ip-url-signing
Where:
<subdomain_name>
: Domain name for which the TLS certificate was created earlier and which will be used by the CDN resource, e.g.,cdn.example.com
.<bucket_name>
: Name of the previously created Object Storage bucket, e.g.,cdn-source-bucket
.--cert-manager-ssl-cert-id
: TLS certificate ID that was saved earlier when creating the certificate.--secure-key
: Secret key, a string of 6 to 32 characters. The secret key will be transmitted to the CDN resource configuration and used to generate and check signed links.
Result:
id: bc8yqhobvxk6******** folder_id: b1gt6g8ht345******** cname: cdn.example.com created_at: "2024-06-22T19:59:05.430376Z" updated_at: "2024-06-22T19:59:05.430394Z" active: true options: edge_cache_settings: enabled: true default_value: "345600" query_params_options: ignore_query_string: enabled: true value: true host_options: host: enabled: true value: cdn-source-bucket.website.yandexcloud.net stale: enabled: true value: - error - updating secure_key: enabled: true key: sdh******** type: ENABLE_IP_SIGNING origin_group_id: "310699" origin_group_name: Origins for cdn.example.com (211929) origin_protocol: MATCH ssl_certificate: type: CM status: READY data: cm: id: fpqia0s2fc21********
For more information about the
yc cdn resource create
command, see the CLI reference.
Use the create REST API method for the Resource resource or the ResourceService/Create gRPC API call.
It may take up to 15 minutes for the new settings of the existing resource to apply to CDN servers. After that, we recommend purging the resource cache.
The content on the new CDN resource will be accessible only via signed links.
Create a CNAME resource record for the CDN resource
-
In the management console
, select the folder to create your resources in. -
Select Cloud DNS.
-
Select the previously created DNS zone.
-
Click Create record.
-
Set the record parameters:
- In the Name field, select
Create subdomain
and specify the name you gave to the CDN resource subdomain. For example, if the domain name of your CDN resource iscdn.example.com
, putcdn
only. - In the Type field, select
CNAME
as the record type. - In the Data field, specify the CNAME record value you copied when creating the CDN resource.
- In the Name field, select
-
Click Create.
-
Get the CNAME record value for the CDN resource:
yc cdn resource get-provider-cname
Result:
cname: cl-ms6*****90.edgecdn.ru folder_id: b1gt6g8ht345********
For more information about the
yc cdn resource get-provider-cname
command, see the CLI reference.Save the obtained
cname
value: you will need it in the next step. -
Create a CNAME resource record in Cloud DNS:
yc dns zone add-records \ --name my-domain-zone \ --record "<subdomain> 600 CNAME <cname_value>"
Where:
<subdomain>
: Subdomain created for the CDN resource. For example, for thecdn.example.com
domain name, specifycdn
.<cname_value>
:cname
value for the CDN resource you obtained in the previous step.
Result:
+--------+------------------+-------+--------------------------+-----+ | ACTION | NAME | TYPE | DATA | TTL | +--------+------------------+-------+--------------------------+-----+ | + | cdn.example.com. | CNAME | cl-ms6*****90.edgecdn.ru | 600 | +--------+------------------+-------+--------------------------+-----+
For more information about the
yc dns zone add-records
command, see the CLI reference.
To get the CNAME record value for a CDN resource, use the getProviderCName REST API method for the Resource resource or the ResourceService/GetProviderCName gRPC API call.
To create a CNAME resource record in a DNS zone, use the updateRecordSets REST API method for the DnsZone resource or the DnsZoneService/UpdateRecordSets gRPC API call.
Publish the webiste on the web server
Next, you will create and publish on your web server a simple website that will generate signed links to content hosted on the secure CDN resource. For data transfer security, you will also copy the previously created TLS certificate to the same web server and enable SSL encryption.
Download the certificate from Certificate Manager
To use the TLS certificate created in Certificate Manager in your web server configuration, download the certificate chain and private key to the current directory:
-
Learn the ID of the previously created TLS certificate:
yc certificate-manager certificate list
Result:
+----------------------+---------------+-----------------------------+---------------------+---------+--------+ | ID | NAME | DOMAINS | NOT AFTER | TYPE | STATUS | +----------------------+---------------+-----------------------------+---------------------+---------+--------+ | fpq90lobsh0l******** | mymanagedcert | cdn.example.com,example.com | 2024-03-22 16:42:53 | MANAGED | ISSUED | +----------------------+---------------+-----------------------------+---------------------+---------+--------+
For more information about the
yc certificate-manager certificate list
command, see the CLI reference. -
Download the key and certificate by specifying the ID obtained in the previous step:
yc certificate-manager certificate content \ --id <certificate_ID> \ --chain ./certificate_full_chain.pem \ --key ./private_key.pem
For more information about the
yc certificate-manager certificate content
command, see the CLI reference.
Configure the web server
-
Copy the obtained certificates and private key to the VM with the web server:
scp ./certificate_full_chain.pem yc-user@<VM_IP_address>:certificate_full_chain.pem \ && scp ./private_key.pem yc-user@<VM_IP_address>:private_key.pem
Where
<VM_IP_address>
is the public IP address of the previously created VM with the web server.You can find the VM IP address in the Network section on the VM page in the management console
or using this CLI command:yc compute instance get mywebserver
.If this is your first time connecting to the VM, you will see an unknown host warning:
The authenticity of host '51.250.**.*** (51.250.**.***)' can't be established. ED25519 key fingerprint is SHA256:PpcKdcT09gjU045pkEIwIU8lAXXLpwJ6bKC********. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])?
Type
yes
in the terminal and press Enter. -
Connect to the VM with the web server.
ssh yc-user@<VM_IP_address>
-
Create a directory for the certificate and move the copied files there:
sudo mkdir /etc/ssl-certificates sudo mv certificate_full_chain.pem /etc/ssl-certificates/ sudo mv private_key.pem /etc/ssl-certificates/
-
Create a directory for your website files and grant the required permissions for it to the
www-data
user:sudo mkdir -p /var/www/<domain_name>/public_html sudo chown www-data:www-data /var/www/<domain_name>/public_html
Where
<domain_name>
is the domain name of your website, e.g.,example.com
. -
Configure a virtual host for your website:
-
Create a virtual host configuration file:
sudo nano /etc/apache2/sites-available/mywebsite.conf
-
Add the following configuration into the file:
<VirtualHost *:443> ServerName <domain_name> ServerAdmin webmaster@localhost DocumentRoot /var/www/<domain_name>/public_html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl-certificates/certificate_full_chain.pem SSLCertificateChainFile /etc/ssl-certificates/certificate_full_chain.pem SSLCertificateKeyFile /etc/ssl-certificates/private_key.pem </VirtualHost>
Where
<domain_name>
is the domain name of your website, e.g.,example.com
. -
Activate the virtual host you created:
sudo a2ensite mywebsite
Result:
Enabling site mywebsite. To activate the new configuration, you need to run: systemctl reload apache2
-
Enable
ssl
for the web server:sudo a2enmod ssl
Result:
Considering dependency setenvif for ssl: Module setenvif already enabled Considering dependency mime for ssl: Module mime already enabled Considering dependency socache_shmcb for ssl: Enabling module socache_shmcb. Enabling module ssl. See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates. To activate the new configuration, you need to run: systemctl restart apache2
-
Restart the web server:
sudo systemctl reload apache2
-
Create a website
-
Create the home page file for the website:
sudo nano /var/www/<domain_name>/public_html/index.php
Where
<domain_name>
is the domain name of your website, e.g.,example.com
. -
Add the following code into the
index.php
file you created:<!DOCTYPE html> <html> <head> <title>Secure token generator website</title> <meta charset="utf-8" /> </head> <body> <h2>Secure link generator</h2> <p>Below, a signed link to the secure CDN resource has been generated. The link is valid for five minutes. The content at this link is available only to the user the link was generated for by the website (verified by IP address).</p> <br> <?php $secret = '<secure_key>'; $ip = trim(getUserIpAddr()); $domain_name = '<cdn_domain_name>'; $path = '<object_key>'; $expires = time() + 300; $link = "$expires$path$ip $secret"; $md5 = md5($link, true); $md5 = base64_encode($md5); $md5 = strtr($md5, '+/', '-_'); $md5 = str_replace('=', '', $md5); $url = '<a href="https://'.$domain_name.$path.'?md5='.$md5.'&expires='.$expires.'" target="_blank">Signed link to file</a>'; echo "<p>Your IP address: <b>".$ip."</b></p><p>If you are using a VPN, you link may not work. For the signed link generator to work properly, disable your VPN.</p>"; echo "<br><br>"; echo $url; function getUserIpAddr() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $addr = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $addr = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $addr = $_SERVER['REMOTE_ADDR']; } return $addr; } ?> </body> </html>
Where:
<secure_key>
: Secret key created when configuring the CDN resource.<cdn_domain_name>
: Domain name of the created CDN resource, e.g.,cdn.example.com
.<object_key>
: Key of the object in the source bucket, e.g.,/content.jpg
. The website generates a signed link to access this object via the CDN resource.
Test secure access to files
To test the generator of signed links to the secure CDN resource:
-
In your browser, go to the website you created, e.g.,
https://example.com
. -
Click the link that was generated.
If everything works as it should, you will see the image hosted on the secure CDN resource.
Note
An active VPN may interfere with the signed link generator's operation. For the website to work correctly, disable your VPN.
-
Open the generated link on another device that uses another IP address to access the internet, e.g., a smartphone.
Access to content will be denied.
-
Try opening the link on the first device after the five-minute timeout expires.
Access to content will be denied.
You have configured secure access to your content.
When generating links, you can also specify a trusted IP address, e.g., an IP used for internet access in your corporate network. Thus you will restrict access to your content from outside your company’s network infrastructure.
How to delete the resources you created
To stop paying for the resources you created:
- Delete the CDN resource, then delete the origin group.
- Delete the objects you created in the bucket, then delete the bucket itself.
- Delete the VM you created.
- Delete the domain zone you created.
- Delete the TLS certificate you created.
- Delete the security group you created, then delete the subnet you created, and finally, delete the network you created.