6.4、批量实现多台服务器之间 SSH 无密码登录的相互信任关系

随笔- 584  文章- 39  评论- 973  阅读- 905万 

批量实现多台服务器之间 SSH 无密码登录的相互信任关系

 

最近IDC上架了一批hadoop大数据业务服务器,由于集群环境需要在这些服务器之间实现ssh无密码登录的相互信任关系。具体的实现思路:在其中的任一台服务器上通过"ssh-keygen -t rsa"产生公私钥文件,然后将公钥文件拷贝成authorized_keys文件,最后将它的.ssh目录下的文件全部批量拷贝到其他服务器的/root/.ssh目录(即当前用户家目录的.ssh)下即可。这批hadoop服务器的ssh端口默认都是22,密码默认都是kevin123456,ip列表如下:

1

2

3

4

5

6

192.168.10.202

192.168.10.203

192.168.10.205

192.168.10.206

192.168.10.207

192.168.10.208

注意:批量部署信任关系后,目标机器的authorized_keys文件不会被覆盖,只会追加,所以如果目标机器之前做了别的信任关系,在新的信任关系做好后,老的信任关系不会丢失。

方法一:  适用于机器数量不多情况  [不推荐,也不安全]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

首先在其中任一台服务器,如192.168.10.202上生产公私钥文件:

[root@server-202 ~]# ssh-keygen -t rsa

[root@server-202 ~]# ls /root/.ssh/

id_rsa  id_rsa.pub

 

[root@server-202 ~]# chmod 600 /root/.ssh/id_rsa                                            #一定要保证私钥id_rsa文件权限是600!

[root@server-202 ~]# cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys

[root@server-202 ~]# ls /root/.ssh/

authorized_keys  id_rsa  id_rsa.pub

 

[root@server-202 ~]# vim /root/hosts

192.168.10.202

192.168.10.203

192.168.10.205

192.168.10.206

192.168.10.207

192.168.10.208

[root@server-202 ~]# for i in `cat /root/hosts`;do rsync -e "ssh -p22" -avpgolr /root/.ssh root@$i:/root/;done

执行该命令后,需要多次手动输入密码

  

执行后,这些机器之间就可以通过ssh密码登录了,即实现了相互信任关系。检查下这些机器的/root/.ssh目录,发现他们的公私钥文件都是192.168.10.202这台机器的。

该种方法仅适用于少数服务器的情况,因为涉及到中途人工交互(输入密码等),如果服务器数量众多的情况下,适用这种方式就比较傻X了,这就需要用到下面这种方法。 

方法二:  使用expect批量做ssh信任
expect是交互性很强的脚本语言,可以帮助运维人员实现批量管理成千上百台服务器操作,是一款很实用的批量部署工具!expect依赖于tcl,而linux系统里一般不自带安装tcl,所以需要手动安装。选择其中的任意一台服务器上操作,比如这里还是选择192.168.10.202这台机器。expect-5.43.0.tar和tcl8.4.11-src.tar 的下载地址:https://pan.baidu.com/s/1kVyeLt9 提取密码:af9p

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

将expect和tcl的软件包下载放到/usr/local/src目录下,解压tcl,进入tcl解压目录,然后进入unix目录进行编译安装

[root@server-202 ~]# cd /usr/local/src/

[root@server-202 src]# tar -zvxf tcl8.4.11-src.tar.gz

[root@server-202 src]# cd tcl8.4.11/unix

[root@server-202 unix]# ./configure

[root@server-202 unix]# make && make install

  

安装expect

[root@server-202 src]# tar -zvxf expect-5.43.0.tar.gz

[root@server-202 src]# cd expect-5.43.0

[root@server-202 expect-5.43.0]# ./configure --with-tclinclude=/usr/local/src/tcl8.4.11/generic --with-tclconfig=/usr/local/lib/

[root@server-202 expect-5.43.0]# make && make install

  

安装完成后进行测试

[root@server-202 ~]# expect

expect1.1>

  

[root@server-202 ~]# which expect

/usr/local/bin/expect

  

做个expect执行文件的软件

[root@server-202 ~]# ln -s /usr/local/bin/expect /usr/bin/expect

[root@server-202 ~]# ll /usr/bin/expect

  

批量实现信任关系的脚本如下:

[root@server-202 ~]# vim /opt/ssh_auth.sh

#!/bin/sh

DEST_USER=$1

PASSWORD=$2

HOSTS_FILE=$3

if [ $# -ne 3 ]; then

    echo "Usage:"

    echo "$0 remoteUser remotePassword hostsFile"

    exit 1

fi

    

SSH_DIR=~/.ssh

SCRIPT_PREFIX=./tmp

echo ===========================

  

# 1. prepare  directory .ssh

mkdir $SSH_DIR

chmod 700 $SSH_DIR

    

# 2. generat ssh key

TMP_SCRIPT=$SCRIPT_PREFIX.sh

echo  "#!/usr/bin/expect">$TMP_SCRIPT

echo  "spawn ssh-keygen -b 1024 -t rsa">>$TMP_SCRIPT

echo  "expect *key*">>$TMP_SCRIPT

echo  "send \r">>$TMP_SCRIPT

if [ -f $SSH_DIR/id_rsa ]; then

    echo  "expect *verwrite*">>$TMP_SCRIPT

    echo  "send y\r">>$TMP_SCRIPT

fi

echo  "expect *passphrase*">>$TMP_SCRIPT

echo  "send \r">>$TMP_SCRIPT

echo  "expect *again:">>$TMP_SCRIPT

echo  "send \r">>$TMP_SCRIPT

echo  "interact">>$TMP_SCRIPT

    

chmod +x $TMP_SCRIPT

    

/usr/bin/expect $TMP_SCRIPT

rm $TMP_SCRIPT

    

# 3. generat file authorized_keys

cat $SSH_DIR/id_rsa.pub>>$SSH_DIR/authorized_keys

    

# 4. chmod 600 for file authorized_keys

chmod 600 $SSH_DIR/authorized_keys

echo ===========================

  

# 5. copy all files to other hosts

for ip in $(cat $HOSTS_FILE)  

do

    if "x$ip" != "x" ]; then

        echo -------------------------

        TMP_SCRIPT=${SCRIPT_PREFIX}.$ip.sh

        # check known_hosts

        val=`ssh-keygen -F $ip`

        if "x$val" == "x" ]; then

            echo "$ip not in $SSH_DIR/known_hosts, need to add"

            val=`ssh-keyscan $ip 2>/dev/null`

            if "x$val" == "x" ]; then

                echo "ssh-keyscan $ip failed!"

            else

                echo $val>>$SSH_DIR/known_hosts

            fi

        fi

        echo "copy $SSH_DIR to $ip"

                    

        echo  "#!/usr/bin/expect">$TMP_SCRIPT

        echo  "spawn scp -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT

        echo  "expect *assword*">>$TMP_SCRIPT

        echo  "send $PASSWORD\r">>$TMP_SCRIPT

        echo  "interact">>$TMP_SCRIPT

            

        chmod +x $TMP_SCRIPT

        #echo "/usr/bin/expect $TMP_SCRIPT" >$TMP_SCRIPT.do

        #sh $TMP_SCRIPT.do&

        

        /usr/bin/expect $TMP_SCRIPT

        rm $TMP_SCRIPT

        echo "copy done."                

    fi

done

    

echo done.

  

  

在上面脚本文件的同目录下新建名为host的文件,将要建立ssh互信的机器名或ip地址添加到该文件中,每个机器名或ip占一行,如:

[root@server-202 ~]# vim /opt/host

192.168.10.202

192.168.10.203

192.168.10.205

192.168.10.206

192.168.10.207

192.168.10.208

  

最后就可以运行这个脚本ssh_auth.sh文件,ssh_auth.sh接受三个参数,远程机器用户名、密码和host文件名(相对路径或绝对路径均可)。

[root@server-202 ~]# sh /opt/ssh_auth.sh root kevin123456 /opt/host

  

然后查看下其他服务器,发现.ssh目录下的文件和192.168.10.202机器的.ssh目录下的文件一致。

最后就可以在这些机器之间进行相互信任的ssh无密码跳转登录了!

  

==========================================================================

注意:上面脚本针对的是服务器ssh端口是22的情况,如果ssh是非22端口,比如是22222端口。

则只需要在ssh_auth.sh脚本中修改下面两行内容:

[root@server-202 ~]# cp /opt/ssh_auth.sh /opt/ssh_auth.sh.bak

[root@server-202 ~]# vim /opt/ssh_auth.sh              #注意下面一个小写p,一个大写P

.......

val=`ssh-keyscan $ip 2>/dev/null`

修改为

val=`ssh-keyscan -p 22222 $ip 2>/dev/null`

.......

echo  "spawn scp -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT

修改为

echo  "spawn scp -P 22222 -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT

  

[root@server-202 ~]# diff /opt/ssh_auth.sh /opt/ssh_auth.sh.bak

57c57

<             val=`ssh-keyscan -p 22222 $ip 2>/dev/null`

---

>             val=`ssh-keyscan $ip 2>/dev/null`

67c67

<         echo  "spawn scp -P 22222 -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT

---

>         echo  "spawn scp -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT

  

最后执行脚本,进行相互信任关系批量部署即可

[root@server-202 ~]# sh /opt/ssh_auth.sh root kevin123456 /opt/host

 

 

Ansible批量更新远程主机用户密码 - 运维笔记

原文地址:https://www.cnblogs.com/kevingrace/p/10601309.html

按照集团运维信息安全制度, 需要每3或6个月对线上服务器密码进行一次变更,通过shell脚本部署比较繁琐,所以决定采用ansible脚本对远程主机root密码进行批量重置,该脚本已经在稳定运行在正式环境下。具体方法如下:

1)  在服务端安装ansible

1

[root@ansible-server ~]# yum install -y ansible

2) 配置ansible到远程主机的ssh无密码登录的信任关系  (authoried_keys 模块)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

首先采用Ansible批量建立ssh无密码登录的信任关系!!

 

[root@ansible-server ~]# ssh-keygen -t rsa          #一路回车

[root@ansible-server ~]# ls /root/.ssh/

id_rsa  id_rsa.pub

  

####################################################################################################

需要注意ssh建立互信的命令格式:

# ssh-copy-id -i ~/.ssh/id_rsa.pub username@ip或hostname

####################################################################################################

  

在客户机比较多的情况下,使用 ssh-copy-id命令的方法显然是有些费时,使用ansible-playbook 推送 ymal进行批量创建ssh互信关系就显得省事多了,

这里就使用到了ansible的authoried_keys 模块:

  

首先要配置ansible清单 (远程主机的密码这里为"123456")

[root@ansible-server ~]# vim /etc/ansible/hosts

................

................

[ssh-host]

172.16.60.204

172.16.60.205

172.16.60.206

172.16.60.207

  

[ssh-host:vars]

ansible_ssh_pass="123456"

  

####################################################################################################

发送公钥到目标机器命令格式如下:

# ansible ssh-host -m copy -a "src=/root/.ssh/id_rsa.pub dest=/root/.ssh/authorized_keys mode=600"

####################################################################################################

在上面分发密钥中,如果清单文件/etc/ansible/hosts里没有使用ansible_ssh_pass变量指明密码,则可以使用下面命令:

这里默认ssh-host组下的机器root密码都一样,使用-k 参数,回车输入root密码即可:

# ansible ssh-host -m authorized_key -a "user=root state=present key=\"{{ lookup('file', '/root/.ssh/id_rsa.pub') }} \"" -k

####################################################################################################

  

编写playbook文件

[root@ansible-server ~]# vim /opt/ssh_key.yaml

---

  - hosts: ssh-host

    user: root

    tasks:

     - name: ssh-copy

       authorized_key: user=root key="{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"

  

注意上面yaml脚本中的"ssh-key-host"是在/etc/ansible/hosts清单文件里配置的远程客户机列表

这里做的是基于远程主机root用户的ssh互信

  

执行批量互信

[root@ansible-server ~]# ansible-playbook /opt/ssh_key.yaml

  

PLAY [ssh-host] ************************************************************************************************************************

  

TASK [Gathering Facts] *****************************************************************************************************************

ok: [172.16.60.204]

ok: [172.16.60.205]

ok: [172.16.60.206]

ok: [172.16.60.207]

  

TASK [ssh-copy] ************************************************************************************************************************

changed: [172.16.60.205]

changed: [172.16.60.204]

changed: [172.16.60.206]

changed: [172.16.60.207]

  

PLAY RECAP *****************************************************************************************************************************

172.16.60.204              : ok=2    changed=1    unreachable=0    failed=0 

172.16.60.205              : ok=2    changed=1    unreachable=0    failed=0 

172.16.60.206              : ok=2    changed=1    unreachable=0    failed=0 

172.16.60.207              : ok=2    changed=1    unreachable=0    failed=0

  

最后验证下ssh互信

[root@ansible-server ~]# ansible -i /etc/ansible/hosts ssh-host -m shell -a "whoami"

172.16.60.204 | SUCCESS | rc=0 >>

root

  

172.16.60.205 | SUCCESS | rc=0 >>

root

  

172.16.60.207 | SUCCESS | rc=0 >>

root

  

172.16.60.206 | SUCCESS | rc=0 >>

root

  

这样,ansible批量创建到远程客户机的ssh信任关系已经实现了!

3) Ansible批量更新远程主机用户密码方法

方法一:  使用Ansible的user模块批量修改远程客户机的用户密码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

由于在使用ansible修改用户密码的时候不能使用明文的方式,需要先加密,所以就需要使用一个方法对输入的明文的密码进行加密.

废话不多说了. 下面直接记录下操作方法:

 

[root@ansible-server ~]# vim /opt/root_passwd.yaml

---

  - hosts: ssh-host

    gather_facts: false

    tasks:

    - name: change user passwd

      user: name={{ item.name }} password={{ item.chpass | password_hash('sha512') }}  update_password=always

      with_items:

           - { name: 'root', chpass: 'kevin@123' }

           - { name: 'app', chpass: 'bjop123' }

 

注意上面在yaml文件中修改了远程客户机的root用户密码, app用户密码.

如果还想要修改其他用户密码, 则继续按照上面规则添加即可!

 

执行ansible-play

[root@ansible-server ~]# ansible-playbook /opt/root_passwd.yaml

 

PLAY [ssh-host] ************************************************************************************************************************

 

TASK [change user passwd] **************************************************************************************************************

changed: [172.16.60.204] => (item={u'chpass': u'kevin@123', u'name': u'root'})

changed: [172.16.60.205] => (item={u'chpass': u'kevin@123', u'name': u'root'})

changed: [172.16.60.204] => (item={u'chpass': u'bjop123', u'name': u'app'})

changed: [172.16.60.205] => (item={u'chpass': u'bjop123', u'name': u'app'})

changed: [172.16.60.206] => (item={u'chpass': u'kevin@123', u'name': u'root'})

changed: [172.16.60.206] => (item={u'chpass': u'bjop123', u'name': u'app'})

changed: [172.16.60.207] => (item={u'chpass': u'kevin@123', u'name': u'root'})

changed: [172.16.60.207] => (item={u'chpass': u'bjop123', u'name': u'app'})

 

PLAY RECAP *****************************************************************************************************************************

172.16.60.204              : ok=1    changed=1    unreachable=0    failed=0  

172.16.60.205              : ok=1    changed=1    unreachable=0    failed=0  

172.16.60.206              : ok=1    changed=1    unreachable=0    failed=0  

172.16.60.207              : ok=1    changed=1    unreachable=0    failed=0

方法二:  修改远程主机的单个用户密码使用此方法比较方便

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

编写playbook文件

[root@ansible-server ~]# vim /opt/root_passwd2.yaml

---

  - hosts: ssh-host

    gather_facts: false

    tasks:

    - name: Change password

      user: name={{ name1 }}  password={{ chpass | password_hash('sha512') }}  update_password=always

 

执行ansible-playbook,  使用-e参数传递用户名和密码给剧本,其中root为用户名,admin#123就是修改后的root密码

[root@ansible-server ~]# ansible-playbook /opt/root_passwd2.yaml -e "name1=root chpass=admin#123"           

 

PLAY [ssh-host] ************************************************************************************************************************

 

TASK [Change password] *****************************************************************************************************************

changed: [172.16.60.204]

changed: [172.16.60.205]

changed: [172.16.60.206]

changed: [172.16.60.207]

 

PLAY RECAP *****************************************************************************************************************************

172.16.60.204              : ok=1    changed=1    unreachable=0    failed=0  

172.16.60.205              : ok=1    changed=1    unreachable=0    failed=0  

172.16.60.206              : ok=1    changed=1    unreachable=0    failed=0  

172.16.60.207              : ok=1    changed=1    unreachable=0    failed=0

方法三:  使用如下Ansible脚本, 适用于修改清单中部分远程主机的用户密码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

编写ansible-playbook脚本 (需要注意下面脚本中"ens192"是客户机ip所在的网卡设备名称, 这个要根据自己实际环境去配置, 比如eth0, eth1等)

[root@ansible-server ~]# cat /opt/root_passwd4.yaml

- hosts: test-host

  remote_user: root

  tasks:

  - name: change password for root

    shell: echo '{{ item.password }}' |passwd --stdin root

    when: ansible_ens192.ipv4.address  == '{{ item.ip }}'

    with_items:

     - { ip: "172.16.60.220", password: 'haha@123' }

     - { ip: "172.16.60.221", password: 'kevin@123' }

     - { ip: "172.16.60.222", password: 'bobo@123' }

 

 执行ansible-playbook:

 [root@ansible-server ansible]# ansible-playbook /opt/root_passwd3.yaml

 

PLAY [ssh-host] ************************************************************************************************************************

 

TASK [Gathering Facts] *****************************************************************************************************************

ok: [172.16.60.204]

ok: [172.16.60.205]

ok: [172.16.60.206]

ok: [172.16.60.207]

 

TASK [change password for root] ********************************************************************************************************

 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address

== '{{ item.ip }}'

 

 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address

== '{{ item.ip }}'

 

skipping: [172.16.60.205] => (item={u'ip': u'172.16.60.204', u'password': u'haha@123'})

 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address

== '{{ item.ip }}'

 

skipping: [172.16.60.206] => (item={u'ip': u'172.16.60.204', u'password': u'haha@123'})

skipping: [172.16.60.206] => (item={u'ip': u'172.16.60.205', u'password': u'kevin@123'})

 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address

== '{{ item.ip }}'

 

skipping: [172.16.60.207] => (item={u'ip': u'172.16.60.204', u'password': u'haha@123'})

skipping: [172.16.60.207] => (item={u'ip': u'172.16.60.205', u'password': u'kevin@123'})

skipping: [172.16.60.207] => (item={u'ip': u'172.16.60.206', u'password': u'bobo@123'})

changed: [172.16.60.205] => (item={u'ip': u'172.16.60.205', u'password': u'kevin@123'})

skipping: [172.16.60.205] => (item={u'ip': u'172.16.60.206', u'password': u'bobo@123'})

changed: [172.16.60.204] => (item={u'ip': u'172.16.60.204', u'password': u'haha@123'})

skipping: [172.16.60.204] => (item={u'ip': u'172.16.60.205', u'password': u'kevin@123'})

skipping: [172.16.60.204] => (item={u'ip': u'172.16.60.206', u'password': u'bobo@123'})

changed: [172.16.60.206] => (item={u'ip': u'172.16.60.206', u'password': u'bobo@123'})

 

PLAY RECAP *****************************************************************************************************************************

172.16.60.204              : ok=2    changed=1    unreachable=0    failed=0  

172.16.60.205              : ok=2    changed=1    unreachable=0    failed=0  

172.16.60.206              : ok=2    changed=1    unreachable=0    failed=0  

172.16.60.207              : ok=1    changed=0    unreachable=0    failed=0

                                                                                                                                                                           

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

如果ansible服务端没有和远程主机做ssh信任关系, 则可以在hosts清单配置里直接指明用户名和密码.

如果使用普通用户, 并且允许sudo, 则需要提前在客户机里的/etc/sudoers文件里配置好该普通用户的sudo配置, 即允许该普通用户有sudo权限.

  

[root@ansible-server ~]# vim /etc/ansible/hosts

................

[test-host]

172.16.60.220 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22

172.16.60.221 ansible_ssh_user=root ansible_ssh_pass=bo@123 ansible_ssh_port=22

172.16.60.222 ansible_ssh_user=app ansible_ssh_pass=bj@123 ansible_ssh_port=22 ansible_sudo_pass=bj@123

  

即172.16.60.222客户机上要提前配置, 允许app用户具有sudo权限.

 

执行:

[root@ansible-server ~]# ansible test-host -m shell -a "hostname"                     

172.16.60.222 | SUCCESS | rc=0 >>

k8s-node02

 

172.16.60.220 | SUCCESS | rc=0 >>

k8s-master01

 

172.16.60.221 | SUCCESS | rc=0 >>

k8s-node01

 

[root@ansible-server ~]# ansible -i /etc/ansible/hosts test-host -m shell -a "hostname"

172.16.60.222 | SUCCESS | rc=0 >>

k8s-node02

 

172.16.60.220 | SUCCESS | rc=0 >>

k8s-master01

 

172.16.60.221 | SUCCESS | rc=0 >>

k8s-node01

*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!***************

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值