花了100块大洋搞懂 ipv6的用户如何访问ipv4 服务器

大家好,今天蓝胖子花了100多块搞懂了 ipv6的用户如何访问ipv4 服务器,将收获与大家分享下。

ipv4和ipv6的协议栈不同,这意味着,其对应的ip包的封装和解析不同,那么只支持ipv4的机器就无法直接与ipv6的服务器进行通信。但目前已经有越来越多人使用ipv6进行通信,如果仅仅让服务器支持ipv4,这无疑会损失一大部分用户,特别是针对于海外业务。

如何让服务器便捷支持ipv4和ipv6都能同时进行访问,就成了我们需要思考的问题。这里我给出几个靠谱方案来解决此类问题。

首先要知道一个http网络请求的流程,我们获取到网站域名后通过DNS协议向DNS服务商请求网站的ip地址,接着才开始向这个ip发送真正的http请求。

在向DNS服务商发出请求过程中,如果用户客户端只支持ipv6,那么它会去DNS服务器查询域名的AAAA记录,如果用户只支持ipv4,那么会去DNS服务器查询A记录

AAAA类型的DNS记录里配置的是域名对应的ipv6地址,A类型记录里则是配置域名的ipv4地址。

linux服务器配置ipv6地址

目前,云服务厂商创建的服务器实例,默认是不分配ipv6的,我们可以通过配置,让其拥有一个ipv6公网ip,接着配置一条AAAA类型的DNS记录,指向这个ip,那么ipv6的用户就可以通过域名访问到服务器了。

我们可以将AAAA记录的域名 和 A记录类型的域名配置成一样。如下,

Pasted image 20240328150910.png

假设,我有个lanpangzi.org 的域名,配置其子域名为www.lanpangzi.org ,并且这个子域名需要同时有ipv4和ipv6的地址,我们就可以对其分别配置A类型和AAAA类型的DNS记录,其中content是对应的公网ip。

这样无论用户是用那种ip协议,都能找到www.lanpangzi.org的对应ip协议的ip地址。

只要得到了域名背后正确的ip地址,那么用户就能正常访问到服务器了。

📢📢📢 但让linux开启ipv6的支持,还是比较繁琐,无论是在厂商侧设置公网ipv6还是本地linux服务器需要改动配置都比较复杂,所以我着重介绍下第二种方式

通过网络代理厂商透明进行协议转换

其实,既然ipv6的用户直接访问ipv4的服务器行不通,那么我们可以加个中间层来转发用户ipv6请求,如下所示,代理商与用户是通过ipv6协议,而与服务器则是通过ipv4。

注意下,用户的请求无论是DNS请求,还是http请求,都应该先通过代理商,DNS请求后代理商返回自己的服务器节点ip,用户再向服务器节点ip发出http请求时,再由该节点对http请求进行转发。

image.png

考察了市面上比较主流的网络代理商后,我选择cloudflare ,接下来,我来演示下如何通过cloudflare 来实现请求代理。

因为我本地的计算还是只支持ipv4,所以我将linux服务器配置成ipv6,演示下ipv4的机器如何访问只支持ipv6的服务器。原理是一致的,都是靠网络代理商转发请求。关于云服务商的服务器如何开启ipv6,我以阿里云为例,其官方文档在下方👇🏻,

https://help.aliyun.com/zh/ecs/user-guide/step-1-create-a-vpc-that-supports-ipv6-addressing?spm=a2c4g.11186623.0.0.341a5048uktqgP#4fbf8a7026p05

ECS 开启ipv6

因为主机默认会有个网卡,我直接去网卡处新增一个ipv6的地址。

Pasted image 20240328160255.png

但默认生成的ipv6还不支持访问公网的能力,如下提示,还需要去交换机处开通公网带宽。

Pasted image 20240328160707.png

开通后的效果如下,

Pasted image 20240328160857.png

接着再配置下实例的安全组,配置成运行任何ipv6的地址访问,因为默认ipv6的包是进不来的。

Pasted image 20240328161417.png

这下才完成了服务器ECS的配置,我们目前的ECS实例已经拥有了一个公网ip了。

域名配置

接着,我们为ipv6公网ip配置一个域名lanpangzi.org,来作为应用程序的域名,用户应该通过www.lanpangzi.org这个域名来访问应用服务

通过dynadot ,我买了一个域名lanpangzi.org

Pasted image 20240328152648.png

接着,在cloudflare 上进行了账号注册,添加自己的域名

Pasted image 20240328155241.png
cloudflare 提供了免费版本,这对于我来说,再好不过了。

Pasted image 20240328155143.png

然后在 cloudflare 界面配置对域名的解析, 需要在域名注册商dynadot那里注册NS记录,来将lanpangzi.org的域名解析交由 cloudflare 。 NS记录的节点是在 cloudflare 配置域名时告诉给开发的。

NS类型的DNS记录,其作用是指明特定域名应该由哪台服务器去解析,这里是将lanpangzi.org 的域名解析交给了 cloudflare 自己的服务器节点。

Pasted image 20240328155541.png

dynadot 的DNS settings处配置NS记录指向 cloudflare 的ns节点 。

Pasted image 20240328154816.png

接着,就是在 cloudflare 上对子域名www进行配置,注意www.lanpangzi.org 我只配置了AAAA记录类型也就是 ipv6的地址。

Pasted image 20240328164028.png

如果仅仅是配置了这样一条AAAA的记录类型,不开启 cloudflare 的代理功能,在ipv4用户发出DNS请求去询问www.lanpangzi.org的ip地址时会因为找不到 ipv4的地址而造成请求失败。如下,我进行了测试,

在ECS上运行了一个go程序,监听80端口,并且将其收到的http请求头打印出来,在未开启代理时,在我本地浏览器对该域名进行访问(我本地的机器只支持ipv4),出现域名解析失败的错误。

Pasted image 20240328164547.png

在开启代理后,则http请求正常,且请求头中有 cloudflare 加的一些自定义头部。

Pasted image 20240328164603.png

Pasted image 20240328164708.png
综上,通过 cloudflare 代理http请求,可以透明的实现用户和服务器间ipv4和ipv6请求的转换,这也是我推荐的方式。

最后,整个域名和服务器的购买,我花了100多块,你们说这个钱,蓝胖子花的值不值。

好的,根据您的需求,我为您设计了一个包含以下表的数据库: 1. 供应商表(supplier):记录供应商的信息,包括供应商编号、供应商名称、所在国家、联系人、联系电话等字段。 2. 零件表(part):记录零件的信息,包括零件编号、零件名称、描述、单价等字段。 3. 供应表(supply):记录供应商和零件之间的供应关系,包括供应商编号、零件编号、供应价、供应能力等字段。 4. 客户表(customer):记录客户的信息,包括客户编号、客户名称、所在国家、联系人、联系电话等字段。 5. 订单表(order):记录客户订单的信息,包括订单编号、客户编号、订单日期等字段。 6. 订单明细表(order_detail):记录订单中每个零件的信息,包括订单编号、零件编号、订购数量等字段。 7. 国家表(country):记录国家的信息,包括国家编号、国家名称、所属洲、所属洋等字段。 根据以上表的设计,以下是 SQL 语句实现数据库模式、基本表的创建: ``` -- 创建国家表 CREATE TABLE country ( country_id INT PRIMARY KEY, country_name VARCHAR(50), continent VARCHAR(50), ocean VARCHAR(50) ); -- 创建供应商表 CREATE TABLE supplier ( supplier_id INT PRIMARY KEY, supplier_name VARCHAR(50), country_id INT, contact_name VARCHAR(50), contact_phone VARCHAR(50), FOREIGN KEY (country_id) REFERENCES country(country_id) ); -- 创建零件表 CREATE TABLE part ( part_id INT PRIMARY KEY, part_name VARCHAR(50), description VARCHAR(100), price DECIMAL(10, 2) ); -- 创建供应表 CREATE TABLE supply ( supplier_id INT, part_id INT, supply_price DECIMAL(10, 2), supply_capacity INT, PRIMARY KEY (supplier_id, part_id), FOREIGN KEY (supplier_id) REFERENCES supplier(supplier_id), FOREIGN KEY (part_id) REFERENCES part(part_id) ); -- 创建客户表 CREATE TABLE customer ( customer_id INT PRIMARY KEY, customer_name VARCHAR(50), country_id INT, contact_name VARCHAR(50), contact_phone VARCHAR(50), FOREIGN KEY (country_id) REFERENCES country(country_id) ); -- 创建订单表 CREATE TABLE order ( order_id INT PRIMARY KEY, customer_id INT, order_date DATE, FOREIGN KEY (customer_id) REFERENCES customer(customer_id) ); -- 创建订单明细表 CREATE TABLE order_detail ( order_id INT, part_id INT, quantity INT, PRIMARY KEY (order_id, part_id), FOREIGN KEY (order_id) REFERENCES order(order_id), FOREIGN KEY (part_id) REFERENCES part(part_id) ); ``` 接下来,我为您提供一些 SQL 语句示例,以便进行数据的插入、更新、查询等操作: 1. 插入数据: ``` -- 插入国家数据 INSERT INTO country (country_id, country_name, continent, ocean) VALUES (1, '中国', '亚洲', '太平洋'), (2, '美国', '北美洲', '大西洋'); -- 插入供应商数据 INSERT INTO supplier (supplier_id, supplier_name, country_id, contact_name, contact_phone) VALUES (1, '供应商A', 1, '张三', '13812345678'), (2, '供应商B', 2, 'John Doe', '1-800-555-5555'); -- 插入零件数据 INSERT INTO part (part_id, part_name, description, price) VALUES (1, '零件A', '描述A', 10.99), (2, '零件B', '描述B', 20.99); -- 插入供应数据 INSERT INTO supply (supplier_id, part_id, supply_price, supply_capacity) VALUES (1, 1, 9.99, 100), (1, 2, 19.99, 50), (2, 2, 18.99, 200); -- 插入客户数据 INSERT INTO customer (customer_id, customer_name, country_id, contact_name, contact_phone) VALUES (1, '客户A', 1, '李四', '13912345678'), (2, '客户B', 2, 'Jane Doe', '1-800-555-5556'); -- 插入订单数据 INSERT INTO order (order_id, customer_id, order_date) VALUES (1, 1, '2022-01-01'), (2, 2, '2022-01-02'); -- 插入订单明细数据 INSERT INTO order_detail (order_id, part_id, quantity) VALUES (1, 1, 5), (1, 2, 10), (2, 2, 20); ``` 2. 更新数据: ``` -- 更新零件B的价格为25.99 UPDATE part SET price = 25.99 WHERE part_name = '零件B'; -- 更新供应商A的联系人为王五 UPDATE supplier SET contact_name = '王五' WHERE supplier_name = '供应商A'; ``` 3. 查询数据: ``` -- 查询所有供应商的名称、所在国家、联系人和电话 SELECT supplier_name, country_name, contact_name, contact_phone FROM supplier JOIN country ON supplier.country_id = country.country_id; -- 查询客户A的所有订单及其明细 SELECT * FROM order JOIN order_detail ON order.order_id = order_detail.order_id WHERE order.customer_id = 1; -- 查询所有供应商提供的零件及其价格 SELECT supplier_name, part_name, supply_price FROM supply JOIN supplier ON supply.supplier_id = supplier.supplier_id JOIN part ON supply.part_id = part.part_id; ``` 以上仅为示例 SQL 语句,具体的数据操作需要根据您的实际需求进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子的编程梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值