在Red Hat Linux 7.3上配置NAT和封包过滤防火墙

原文地址:http://www.ta139.com:8080/~pangty/MyLinux/iptables.htm

实际工作中我们会有这样的需求:让多台计算机/局域网共享一条线路访问Internet,要实现这项功能通常有两种方法:

 

l         使用NATNetwork Address Translation)

l         架设代理服务器Proxy Server)

 

一个典型的应用环境如下图所示:

图中我们把网络划分为两个区域:Private区和Internet区。对外提供服务的Internet服务器也放在Private区,和局域网其它主机使用同一网段地址(当然,也可以不单独设Internet服务器而在接入服务器上安装Internet服务)。Linux接入服务器就是我们下面工作的重点,它负责带动局域网内的主机访问Internet,并保护局域网内的主机和服务器不受来自Internet的攻击。

 

为方便后面的脚本编写,首先来明确几个必要的参数。Linux接入服务器上面向Internet的网卡eth0配置如下,这些数据是从ISP那里得到的:

IP地址 61.156.35.114(只有一个公网IP地址,这么少?足够了)

子网掩码 255.255.255.192

网关地址 61.156.35.126

DNS服务器 202.102.152.3 202.102.134.68

局域网内的IP地址是192.168.100.0/255.255.255.0,我们在局域网内部安装了Internet服务器,地址为192.168.100.1,通过设置Linux接入服务器上的安全规则使它可以对外提供www、smtp、pop3等服务。Linux接入服务器上面向Private的网卡是eth1,其IP地址为:IP地址 192.168.100.254。

 

在接入Internet时,直接连接到Internet上的计算机是安全问题的焦点。无论是一台计算机还是由计算机连接起来的局域网(LAN),其焦点都是与Internet直接相连的机器(或设备),这台机器按照其功能人们通常称之为Internet网关、防火墙或代理服务器,我习惯于称它为Internet接入服务器。

 

作为接入服务器:我们希望我们的局域网可以共享我们的Internet连接,并且根据实际情况的需要,控制局域网内主机或用户能否通过这个网关自由或有限的访问Internet。如果局域网访问Internet的流量较大,使用频繁,我们还希望这台主机能够实现各种缓存功能(DNS缓存、WEB缓存),以减少流量和加快访问速度。

 

作为防火墙:我们在局域网内运行着本地私有服务,诸如共享打印机或共享文件系统,我们希望这些服务仅在局域网内有效,或者某些服务可以公开到Internet上,这可以通过设置相应的安全策略来实现。

 

图中的Linux接入服务器所实现的就是我们常说的代理服务器/防火墙。局域网内的终端通过Linux服务器来访问Internet,Linux 服务器是局域网和Internet连接之间的一个网关(Gateway),这时所有对Internet的访问都会经过Linux服务器。

 

从共享上网的功能来看,NAT的优点是局域网用户通过NAT方式上网时客户端不需要作任何的特殊设置,就和直接使用公网IP地址上网没什么区别;而Proxy则更方便对用户进行权限控制,并且还可以实现访问内容的本地缓存,以此加快访问速度以及内容过滤等等。

 

NAT和Proxy在Linux上的实现是Linux的典型应用之一,并且还可以结合NAT和Proxy配置透明代理(Transparent Proxy),实现两者的完美结合。本文就来介绍一下Linux NAT和封包过滤(Packet Filtering)防火墙。

 

 

§§ 安装iptables

 

开始之前有必要了解一下Linux内核对NAT、防火墙功能支持的历史,Linux内核在不同的版本使用不同的系统来实现这些功能:

Linux 2.0内核使用ipfwadm实现,实际应用中2.0版的内核已经不太常见了;

Linux 2.2内核使用ipchains实现,我的主页上摘录了一篇相当棒的关于ipchains的教程,正在使用Linux 2.2版内核的朋友可以阅读参考:

http://www.ta139.com:8080/~pangty/ipchains/0.htm

Red Hat Linux 7.3使用的是2.4版内核,Linux 2.4内核实现这部分功能的机制是netfilter和iptables,这个系统可以完成封包过滤(packet filtering)、网络地址转换NAT(network address translation)以及其它对数据包(packet)的操作。

 

netfilter是Linux 2.4.x内核内嵌的功能,由它实现对流经它的数据包的处理,iptables则被定义成一个规则表格,用来描述如何对封包进行处理。netfilter、iptables、连接跟踪、以及NAT功能共同组成了Linux 2.4.x内核的网络安全体系。除了通过NAT让局域网共享线路上网之外,这些功能还可以让你在Linux上创建一个功能完善的防火墙系统。

 

很多文章在讲iptables时都会提到要重新编译内核以提供对netfilter和iptables的支持,这让大多数的新手感到无从下手。实事上,目前广泛应用的各种Linux发行版的内核已经提供了默认支持,除非特别需要,没有必要进行内核的重编译。

 

首先安装iptables软件包。查询一下系统上是否安装了iptables软件包:

 

[root@rh73 ~]# rpm -qa|grep iptables

 

如果没有,那么找到Red Hat Linux 7.3的安装光盘,开始安装iptables:

 

[root@rh73 /mnt/cdrom/Red Hat/RPMS]# rpm -ivh iptables-1.2.5-3.i386.rpm

Preparing...                ########################################### [100%]

   1:iptables               ########################################### [100%]

 

还要注意的一点是,Red Hat Linux高版本(7.1版之后)开始正式支持iptables,但仍会同时提供基于Linux 2.2.x内核的ipchains。这两个系统是不能同时存在的,因此,有必要确认并停止ipchains的服务:

 

[root@rh73 ~]# /etc/rc.d/init.d/ipchains stop

[root@rh73 ~]# chkconfig --level 0123456 ipchains off

 

如果更彻底一点,可以把已经安装的ipchains卸载掉:

 

[root@rh73 ~]# rpm -e ipchains

 

 

§§ 最简单的NAT脚本

 

为了更直观的认识在Linux上实现NAT,我们先来编写一个脚本fw.sh,其内容如下:

 

#!/bin/sh

echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 61.156.35.114

 

只有三行,写完后存盘。然后修改文件属性,加上可执行权限:

 

[root@rh73 ~]# chmod +x fw.sh

 

运行这个脚本

 

[root@rh73 ~]# ./fw.sh

 

到客户端试一下。如果你不是使用前面介绍的DHCP给客户端机器自动配置网卡参数,则需要手工的配置客户端网卡的IP地址、子网掩码、默认网关(根据前面安装时的配置,这里应该是Linux服务器上eth1的地址192.168.100.254),以及ISP提供给你的DNS服务器地址。现在浏览器里输入一个网址 ... ... 如果没有什么意外,现在已经可以上网了!

 

回过头来看看这个脚本:

 

echo 1 > /proc/sys/net/ipv4/ip_forward

 

这一行是通知Linux内核启动ip转发,只有启动了ip转发功能才能使用NAT。

 

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 61.156.35.114

 

这一行的意思是:把来自192.168.100.0子网并通过eth0出去的访问请求做NAT,把数据包的源地址修改为61.156.35.114。192.168.100.0/24也可以写成192.168.100.0/255.255.255.0,24代表了子网掩码掩到第24位,即255.255.255.0。

 

如果你的ISP没有分配给你固定的公网地址,那么这一行可以写成:

 

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j MASQUERADE

 

modem或isdn等拨号方式上网,假如是通过ppp0拨号上网,可以这样写:

 

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o ppp0 -j MASQUERADE

 

这是NAT是一种特例,我们称其为IP伪装(masquerading)。

 

这里是针对一个子网(192.168.100.0/24)做NAT,也可以具体到某台主机:

 

iptables -A POSTROUTING -t nat -s 192.168.100.9 -o eth0 -j MASQUERADE

 

 

§§ NAT——Network Address Translation

 

让我们仔细来了解一下Linux 2.4的NAT。前面我们编写的脚本中使用NAT功能可以带动局域网访问Internet,而Linux的NAT可以做的事情远不止这些。

 

NAT table中,数据包通常被送到几个不同的目的地DNAT、SNAT和MASQUERADE,通常我们可以根据这个把NAT分为两种不同的类型:Destination NAT(DNAT)和Source NAT(SNAT)。

 

Destination NAT将改变数据包要到达的目的地。使用DNAT我们可以把来自Internet上发送到我们的真实IP地址上的请求转发到内部的某台服务器上,比如我们把内部的两台服务器分别配置成公司的WEB服务器和MAIL服务器,通过设置DNAT规则,可以把外部对我们服务器公网地址的WWW请求,送到局域网内部的WEB服务器上,也可以把MAIL服务的请求,送到内部的MAIL服务器上,这种NAT以前也被称为端口转发。

 

重定向(Redirection)是Destination NAT的一个特例。某些场合我们人为的把经过Linux的数据包送往本机的另外一个程序来处理,比如我们知道使用代理服务器程序的缓存功能可以加快访问Internet的速度,这在使用速度较低的Internet连接时非常有意义。这时就可以把经过Linux服务器访问Internet的请求送给某个代理服务程序,由该代理服务器完成访问请求,我们经常提到的透明代理就是这种方式,之所以称为透明,是因为在这种工作方式下你感觉不到代理的存在。squid可以配置完成这项工作。

 

Source NAT改变数据包的来源地址。使用SNAT最典型的例子就是前面我们那个脚本实现的功能,这时,来自内部局域网通过Linux接入服务器的packet的源地址都被修改为服务器外网卡的公网地址。这样也可以起到隐藏内部地址的作用,无论你从内部的哪台机器上访问Internet,从Internet上看到的,都是你的外网卡的IP地址。

 

伪装(masquerading)是SNAT的一种特殊形式,在使用上和SNAT完全一样。两者的区别在于:在Internet接入时,如果服务器端使用的是DHCP、拨号等没有固定IP地址的接入方式,masquerading可以自动的判断使用哪个IP地址,而SNAT则更多的用于有固定IP地址的场合。

 

 

§§ 控制NAT规则表

 

前面已经看到了,我们使用iptables来创建NAT规则,使用-t nat参数来修改NAT table,告诉Linux内核哪些连接请求将被改变和如何改变。

 

NAT规则表包含两个称为“chains”的列表:PREROUTING(用于Destination NAT,当包进入时检查);POSTROUTING(用于Source NAT,包离开时检查,我们前面已经用过了)。通过NAT主机的数据包按顺序与规则表内的规则匹配。如下图所示:

            _____                                     _____

           /     /                                   /     /

    -->--PREROUTING -->[Routing ]----------------->POSTROUTING----->

           /D-NAT/     [Decision]                    /S-NAT/

                           |                            ^

                           |                            |

                           |                            |

                           |                            |

                           |                            |

                           |                            |

                           |                            |

                           --------> Local Process ------

 

这个图表描述了经过Linux服务器的数据包是被如何处理的,数据包通过Linux服务器时进行路由操作,并且被检查是否与DNAT或SNAT规则匹配,与规则匹配的数据包将被作相应处理。

 

下面举例说明如何使用iptables来定义NAT规则

 

Source NAT

 

Source NAT在数据包送出之前改变数据包的源地址,其规则在POSTROUTING chain中定义。

 

几个参数:

-j SNAT 定义SNAT

--to-source 指定转换后的源地址[:port],可以简写成--to

[:port],端口,是一个可选项,仅在指明TCP或UDP协议时使用

-o 出口接口outgoing interface)

 

举例:

 

把数据包源地址转换为 1.2.3.4.

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

还有前面我们用到的

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 61.156.35.114

 

把数据包源地址转换为1.2.3.4, 1.2.3.5 或 1.2.3.6

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6

 

把数据包源地址转换为1.2.3.4, 使用端口范围是1-1023

iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

 

伪装Masquerading)

 

伪装是Source NAT的一种特例,常用在诸如拨号上网等使用动态IP地址的情况下:

 

伪装所有通过ppp0送出的数据包

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

 

有固定IP地址的时候也可以使用IP伪装,比如前面我们用到的

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 61.156.35.114

也可以写成

iptables -t nat -A POSTROUTING -s 192.168.100.0/24 –o eth0 -j MASQUERADE

 

Destination NAT

 

Destination NAT规则在PREROUTING chain中定义,它改变数据包中目的地址的值。

 

几个参数:

-j DNAT 定义DNAT

--to-destination[:port] 指定转换后的目标地址[:port],可以简写成--to

[:port],端口,是一个可选项,仅在指明TCP或UDP协议时使用

-i 入口接口 (incoming interface)

 

举例:

 

转换数据包目标地址为 5.6.7.8

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8

 

转换数据包目标地址为 5.6.7.8, 5.6.7.9 or 5.6.7.10.

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10

 

改变WWW访问请求的目标地址到5.6.7.8的8080端口

iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 /

        -j DNAT --to 5.6.7.8:8080

 

重定向Redirection)

 

重定向是Destination NAT的一个特例。比如我们经常提到的squid透明代理是把客户端对80端口的请求(WWW请求)重定向送到squid代理:

iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 /

        -j REDIRECT --to-port 3128

 

 

§§ 使用NAT时对特殊协议的处理

 

除了上网浏览页面,我们还可能需要用到其它的Internet服务,比如ftp,现在我们打开一个DOS窗口,登录到某个ftp服务器,如下图:

 

注意一下这个提示信息:

 

500 Illegal PORT command.

425 Can't build data connection: Connection refused

 

我们现在无法正常列出该ftp服务器上的内容,更无法传送文件了。

 

来看看是什么原因:FTP一般需要使用两个端口,端口21只是一个命令端口, 真正传送数据的时候, 还需要另外一个数据端口(通常是TCP/UDP 20)。问题就出现在第二个数据端口上。打开这个数据端口的时候有两种方式,一种是passive(PASV command)方式,由FTP Server端提供一个连接的IP/Port,FTP Client连接到这个IP/Port上进行数据传输。另一种是active(PORT command)方式,由FTP Client提供IP/Port,再由FTP Server回叫至Client提供的地址。具体采用哪一种方式, 是由FTP Client决定的,Client通过PASV或PORT命令通知Server采用什么方式。正是这样的握手方式,给Server端和Client端都造成了麻烦。这个问题的具体描述详见http://www.daemonnews.org/200109/ftpnat.html

 

对于客户端来说,有这样几种情况:

 

FTP Client采用passive方式,告诉FTP Server端提供一个数据端口。一般的FTP Client软件都支持passive方式,我使用的网络蚂蚁,网际快车(FlashGet)默认方式都是passive。

 

FTP Client不支持passive方式或者使用浏览器作为FTP Client。通过浏览器直接访问FTP使用的是active方式,问题就出现在这里。

 

另外还有一些FTP站点不支持passive方式。这时,就需要我们修改Linux NAT,添加相应的模块来支持active模式:

 

[root@rh73 ~]# modprobe ip_nat_ftp

[root@rh73 ~]# modprobe ip_conntrack_ftp

 

这时再登录访问ftp就没有问题了。类似的,其他服务如irc也有对应的模块来支持。可以把这两行内容写在fw.sh里面:

#!/bin/sh

 

modprobe ip_nat_ftp

modprobe ip_conntrack_ftp

 

echo 1 > /proc/sys/net/ipv4/ip_forward

 

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 61.156.35.114

 

 

§§ Destination NAT到同一网络内

 

如同在前面的网络拓扑里描述的,实际应用中,我们还可能会把内部的某台主机作为服务器对外提供服务,这就可能遇到DNAT到同一网络内的问题。最典型的例子是:在内部我们有一台服务器运行着web服务,现在我们想让Internet上的用户通过Linux服务器来访问到它。

 

比如,让内部的192.168.100.1这台服务器充当web服务器,当别人把访问web的请求发送到我们的公网地址,假设为61.156.35.114,通过设置DNAT规则,让内部的192.168.100.1来做出响应:

 

iptables -t nat -A PREROUTING -d 61.156.35.114 -p tcp --dport 80 -j DNAT --to 192.168.100.1

 

假设我申请了域名www.silly.com指向61.156.35.114,从公网上访问http://www.silly.com是没有问题的,但从192.168.100.0这个网络上的终端却无法用http://www.silly.com来访问web服务,因为Linux NAT只对穿过它的数据包做修改,而来自内部的访问请求恰恰在到达Linux服务器的外网卡接口时即被环回了。

 

解决问题的办法有两个:

 

a、设置一个内部的DNS,把你的域名www.silly.com指向到内部的IP地址192.168.100.1,其它的域名解析正常进行。这样,当你从内部访问www.silly.com时,你的DNS会自动把它指向192.168.100.1,而不经过Linux服务器。

 

b、修改NAT规则,增加这样一行:

iptables -A POSTROUTING -s 192.168.100.0/255.255.255.0 -d 192.168.100.1 -p tcp -m tcp --dport 80  /

-j SNAT --to-source 192.168.100.254

 

截止到这里,我们已经知道如何使用iptables来设置NAT规则实现从局域网到Internet的访问,并且知道了如何利用ip地址或网卡MAC地址控制上网权限。如果在局域网内设置了Internet服务器,我们还可以通过设置DNAT规则来实现从Internet到局域网内特定服务的访问。

 

 

§§ 封包过滤——Packet Filter

 

刚才使用NAT解决了局域网接入问题,现在就来看看netfilter的强大的封包过滤功能,该功能常被用来配置防火墙。

 

封包过滤(Packet Filter)是使用特定的软件来察看经过Linux服务器的数据包的包头,并根据过滤规则的设置决定数据包的命运。比如丢弃(DROP)该数据包,接收(ACCEPT)该数据包(允许通过),或者其它的动作。

 

 

§§ 控制封包过滤规则

 

来看看Linux下的封包过滤是如何工作的。Linux内核中默认的有三个被称为“防火墙规则”的过滤表,分别是:INPUT、OUTPUT和FORWARD。如下图所示:

                                  _____

        Incoming                 /     /         Outgoing

           ------>[Routing ]--->|FORWARD|-------->

                  [Decision]     /_____/         ^

                       |                         |

                       v                       ____

                      ___                     /    /

                     /   /                   |OUTPUT|

                    |INPUT|                   /____/

                     /___/                       ^

                       |                         |

                        ----> Local Process -----

 

数据包通过网络接口(比如网卡)进入Linux服务器,首先,该数据包将被进行路由操作(Routing Decision)以决定它的去向,然后分别与INPUT、FORWARD、OUTPUT规则表匹配以决定是否允许该数据包通过或转发。防火墙规则表完全决定了通过该服务器的数据包的命运。

 

对照我们前面描述的网络连接,我们通过Linux服务器上的eth0连接到Internet,下面修改后的脚本将在实现NAT的同时,禁止任何来自Internet的主动访问,即整个网络的访问权限是单向的,只允许从内部网向Internet的访问。

[root@rh73 ~]# cat fw.sh

#!/bin/sh

 

modprobe ip_nat_ftp

modprobe ip_conntrack_ftp

 

echo 1 > /proc/sys/net/ipv4/ip_forward

 

#把默认的INPUT和FORWARD策略置为DROP

iptables -P INPUT DROP

iptables -P FORWARD DROP

 

#禁止来自Internet到eth0主动发起的访问请求

iptables -A FORWARD ! -i eth0 -m state --state NEW -j ACCEPT  ①

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT  ②

 

iptables -A INPUT ! -i eth0 -m state --state NEW -j ACCEPT  ③

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  ④

 

iptables -A POSTROUTING -t nat -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 61.156.35.114

 

由于对于INPUT和FORWARD的规则设置相同,也可以把①②③④部分简化一下:

#创建一个新的规则表allowed

iptables -N allowed

iptables -A allowed ! -i eth0 -m state --state NEW -j ACCEPT

iptables -A allowed -m state --state ESTABLISHED,RELATED -j ACCEPT

 

#INPUT和FORWARD使用allowed规则表的设置

iptables -A INPUT -j allowed

iptables -A FORWARD -j allowed

 

这个脚本中又用到了iptables的几个新的参数和使用方法,下面将对此做一个小小的总结。

 

 

§§ iptables的常用命令和选项

 

前面我们一直使用iptables这个工具来创建和维护规则表,它通过丰富的命令和选项来设置这些规则,到目前为止本文只讲述其中很少的一部分内容,但我想在大多数场合下这已经足够用了,(但愿你也这么认为 8))。

 

iptables命令:

 

维护规则表的命令:

1.       -N)创建一个新规则表

2.       -X)删除一个空规则表

3.       -P)改变内建规则表的默认策略

4.       -L)列出规则表中的规则

5.       -F)清空规则表中的规则

6.       -Z)将规则表计数器清零

 

管理规则表中的规则:

1.       -A)添加新规则到规则表

2.       -I)插入新规则到规则表的某个位置

3.       -R)替换规则表中的规则

4.       -D)删除规则表中的某条规则

 

在调试iptables规则时,你也许需要反复修改你的脚本来实现某些特定的功能,这时建议在你的脚本里添加这样几行,以防止重复设置规则:

 

# 清除所有规则

iptables -F -t filter

iptables -X -t filter

iptables -Z -t filter

iptables -F -t nat

iptables -X -t nat

iptables -Z -t nat

 

# 设置内建规则表的默认策略

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -t nat -P PREROUTING ACCEPT

iptables -t nat -P POSTROUTING ACCEPT

iptables -t nat -P OUTPUT ACCEPT

 

-t”选项是“--table”的简写,它指明了你要对哪类规则表进行操作,默认的是指filter。

 

下面举例说明iptables的部分选项的使用:

 

指定源地址和目标地址

 

指定规则操作的源地址  -s 或 --source 或 -src

指定规则操作的目标地址 -d 或 --destination 或 -dst

 

允许来自192.168.100.0/24的数据包通过

iptables -A INPUT -s 192.168.100.0/24 -d 0.0.0.0/0 -j ACCEPT

 

-j”选项是“--jump”的简写,它指明了匹配该条规则的数据包的具体处理方法,可能是ACCEPT、DROP等。

 

取反:在参数前加“!”号

 

接受除了来自192.168.100.0/24外的所有的数据包

iptables -A INPUT -s ! 192.168.100.0/24 -d 0.0.0.0/0 -j ACCEPT

 

指定协议TCP、UDP或ICMP)

 

-p 或 --protocol

 

禁止icmp协议

iptables -A INPUT -p icmp -j DROP

 

指定接口

 

指定数据包进入的接口 -i 或 --in-interface

指定数据包送出的接口 -o 或 --out-interface

INPUT规则表中只允许指定-i接口,OUTPUT规则表中只允许指定-o接口,FORWARD表可以指定这两种接口。

 

允许从eth1进入的数据包

iptables -A INPUT -i eth1 -j ACCEPT

 

允许从eth0接口送出的数据包

iptables -A OUTPUT -o eth0 -j ACCEPT

 

转发从eth1进入,eth0送出的数据包

iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

 

TCP/UDP扩展

指定源端口 --sport 或 --source-port

指定目的端口 --dport 或 --destination-port

 

允许从eth0进入访问到目标端口为21的tcp数据包

iptables -A INPUT -i eth0 -p tcp --dport 21 -j ACCEPT

 

允许从eth0进入访问到目标端口为21的udp数据包

iptables -A INPUT -i eth0 -p udp --dport 21 -j ACCEPT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值