Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network Engineering 网络工程师 #35

Open
28 of 30 tasks
solomonxie opened this issue Jan 26, 2018 · 92 comments
Open
28 of 30 tasks

Network Engineering 网络工程师 #35

solomonxie opened this issue Jan 26, 2018 · 92 comments
Milestone

Comments

@solomonxie
Copy link
Owner

solomonxie commented Jan 26, 2018

日常的网络问题层出不穷,实在太多有点记忆不够用,在这里开一篇再好不过,随时查阅。
另外,基础的网络学习也一起放在这吧

区分:这里探讨互联网protocol协议相关的所有内容,唯独不涉及TCP/IP协议族的最高层 Application Layer。App应用因为太丰富,且已经抽象成为了业务相关的内容,为表区分就单放在另一篇中。

涉及问题

  • Protocols 互联网协议
    • TCP/IP
    • HTTP
    • HTTPS / SSL
    • CA / DV / OV / EV
  • Troubleshooting 网络诊断
  • Web monitor 网络监控
    • netstat
    • dstat
    • Netdata
  • Web traffic sniffing 抓包分析
    • Wireshark
  • Proxy 代理
    • Shadowsocks
  • 公网映射
    • SSH Tunnel
    • FRP
  • 网络连接
    • SSH 终端连接
    • Mosh 终端连接
    • VNC (Linux/Unix) 远程桌面
    • RDP (Microsoft Remote Desktop Protocol) 远程桌面
  • 网络传输 Transfer
    • FTP
    • SFTP
    • scp
    • rsync
  • 网络文件共享 File Sharing Protocol
    • Webdav / Wsgidav
    • Samba
@solomonxie
Copy link
Owner Author

很多github.io个人网站打不开

排除过超多原因(VPN, hosts,ISP,DNS)后,发现只针对github.io的话,最主要的是github.io全线强制性改成了必须用https访问。所以很多repo中显示的github.io的链接前没有加https://就会造成打不开链接。

@solomonxie
Copy link
Owner Author

solomonxie commented Jan 26, 2018

访问谷歌被屏蔽 (未解决)

访问谷歌时被谷歌强制验证,通过验证后才能访问谷歌。这种一般是走代理访问时才会发现。

image

检查DNS设置可能会有帮组

@solomonxie solomonxie changed the title Network Troubleshooting 网络诊断 Network网络诊断 Jan 26, 2018
@solomonxie solomonxie changed the title Network网络诊断 Network 网络诊断 Jan 26, 2018
@solomonxie
Copy link
Owner Author

solomonxie commented Feb 1, 2018

Shadowsocks 服务器安装

1.创建服务器
2.创建时选择SSH Key,上传本地制作的密钥文件,如~/.ssh/id_rsa.pub
3.记住本地SSH Key密钥的访问密码,这样每次登录服务器只要输入它就行了。
4.打开终端, 利用SSH连接,如DigitalOcean是$ ssh root@ip-address,Lightsails就是$ ssh ubuntu@ip-address

sudo apt-get update
sudo apt-get install python-pip -y
# 如果提示需要升级pip
# pip install --upgrade pip
pip install shadowsocks
sudo vi /etc/shadowsocks.json
{
    "server":"0.0.0.0",
    "server_port": 1111,
    "password":"aaaaaaaa",
    "local_address":"127.0.0.1",
    "method":"aes-256-cfb",
    "local_port":1080,
    "timeout":300,
    "fast_open":false
}

sudo ssserver -c /etc/shadowsocks.json -d start

如果遇到 permission denied错误, 试一下改变下面文件权限:

sudo chmod 777 /var/run/shadowsocks.pid
sudo chmod 777 /var/log/shadowsocks.log

如果还是不行,那么试试直接按照ssserver的路径启动:

sudo /usr/local/bin/ssserver -c /etc/shadowsocks.json -d start

image

@solomonxie solomonxie changed the title Network 网络诊断 Network Engineering and Troubleshooting 网络诊断 Feb 5, 2018
@solomonxie
Copy link
Owner Author

solomonxie commented Feb 5, 2018

❖ HTTP协议 学习 [DRAFT]

主要看阮一峰入门:
http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html

http://www.ruanyifeng.com/blog/2012/06/internet_protocol_suite_part_ii.html

http://www.ruanyifeng.com/blog/2016/08/http.html

互联网协议,实际上不管是7层还是5层,
说白了就是一个洋葱,一层一层被剥开。
不管二进制码怎么样,直接用json直白一点:

{ //实体层
    “Head”: "头",
    “Data: { //链接层
        “Head”: “头”,
	    “Data: { //网络层
	        "Head": "头",
	        "Data": { // 传输层
	        	"Head": "头", 
	        	"Data": { //应用层
	        		"Head": "头",
	        		"Data": ""
	        	}
	        }
	    }
    }
}

@solomonxie
Copy link
Owner Author

Chrome无法访问某特定网页 但是Safari和其它浏览器能正常访问

实际上这个“疑难杂症”系列的开启,就是源于今天近一个小时解决Chrome无法访问Github.io的问题。
由于现在在国内,所以装了各种Shadowsocks和Chrome切换代理插件,甚至还修改了本地的Hosts文件。所以一旦遇到无法访问网页,真是要伸手到很多地方去开启、关闭、各种调试。不过最终终于在chrome的插件管理里面找到了问题。

尝试方法

由于之前安装了AdBlock插件,删除它
实际上我装了以后一直没有使用这个插件,因为会被很多网站检测到并提示这个做法不道德。所以我就长期将这个插件放在不启动模式。但是没想到即便不启动,它仍然有屏蔽一些网站的功能。导致我无法访问github.io的各种个人主页。

解决方案后记

删除adblock插件后没多久就又无法访问了,所以再想别的问题。不断尝试后发现,只要把所有的url地址都强制改为https://安全链接,就能访问。

@solomonxie solomonxie changed the title Network Engineering and Troubleshooting 网络诊断 Network Engineering and Troubleshooting Feb 5, 2018
@solomonxie
Copy link
Owner Author

用Postman对手机抓包

一般人会抓头,Postman明明是API调试工具,和抓包有什么关系。其实这也就是官方对一个小tip,本身存在是为了监控本机某端口数据包的。但其实,如果指定某一个监视端口,然后让同局域网的手机通过这台电脑的这个端口联网而已。这样的话Postman就间接监控到了手机数据包。
操作没有任何难度,主要就是大家对手机将电脑视为代理连接比较陌生罢了。注意:不是让电脑开启热点充当wifi,而是手机本身已经连了wifi时设置代理为电脑而已。
具体操作在Postman官网博客中

@solomonxie solomonxie added the HF High frequency notes label Feb 9, 2018
@solomonxie solomonxie added this to the TOP NOTES milestone Feb 9, 2018
@solomonxie
Copy link
Owner Author

solomonxie commented Feb 9, 2018

命令行方式的网络测速 Speed Test

一般最靠谱的网速测速是Ookla Speedtest这个网站,不管在国内还是国外。
snip20180209_69

不过其实它还有命令行的访问方式,这种方式最适合树莓派或者远端服务器这样的看不到显示器的网速测试。
直接在命令行里一句话(是一个词就够)就能返回一系列的测试结果。
官方Github网站在这里:https://github.com/sivel/speedtest-cli
安装方式是:只要在自己或者服务器的命令行里输入sudo pip install speedtest-cli即可,下载好后,直接在命令行里输入sppedtest-cli,回车,就会出现测试过程和结果。
snip20180209_67

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 9, 2018

让curl通过shadowsocks连接

shadowsocks是Socks5的连接方式。本地打开shadowsocks的客户端后,找到它在本机使用的端口。比如1080。然后输入如下命令就可以查看到效果:

curl --socks5-hostname localhost:1080 http://httpbin.org/ip

其中 http://httpbin.org/ip 是一个可以返回访问者ip地址的网站。
如果你的命令行返回的是你的服务器ip,那么就成功。
实践成功。

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 18, 2018

❖ Linux上各种网络端口流量监控的工具对比使用

尝试过太多了,总结:都没太大用处,顶多也就看看当前系统某网卡的进出流量。最后还是系统默认的iftop最靠谱。

一键安装所有常用的网络监视软件:

# Ubuntu
sudo apt-get install -y iftop dstat nload iptraf ifstat nethogs bmon slurm vnstat bwm-ng cbm speedometer 

#Mac 
brew install iftop dstat nload iftraf ifstat nethogs bmon slurm vnstat bwm-ng cbm speedometer 

iftop 统计所有端口流量 (没法统计某个端口)

一般是默认安装的,
需要sudo权限:sudo iftop
参考文章
image

参考文章
image

iptraf

能够看到每个网卡的当前流量,如600 kbits/sec
注意,一开始的显示颜色会很难看,需要艰难地在菜单里选择color,然后重启程序,才能正常显示。
image

bmom

动态柱状图显示进、出的流量和秒速。页面比较友好,信息简单。
image

vnstat

画面简单,但不是动态的。只是总结日平均、月平均等。
image

bwm-ng

功能超少超简单,只显示进出流量。
image

cbm

只显示进出流量。
image

speed-meter

需要输入speedometer -r eth0 -t eth0 执行。
只显示简单信息。但是带颜色和每个峰值的标注的界面好看。
image

slurm

命令是slurm -s -i eth0 。信息很少:
image

ntop

安装还需要用户名密码,这对于服务器来说太不友善了。装完了后,还打不开。。。

dstat

可读性不强,也没什么好玩的显示出来。
image

nload

画面简单,沾满全屏,只告诉你当前incoming和outgoing的流量速度。
image

ifstat

极其简单只显示两个数值:进和出的秒速。
image

nethogs

需要sudo才有权限运行。
按用户显示每个用户所用的流量,基本上没什么用,数值也少。
image

@solomonxie solomonxie changed the title Network Engineering and Troubleshooting Network Troubleshooting Feb 26, 2018
@solomonxie solomonxie changed the title Network Troubleshooting Network Troubleshooting 网络故障排除 Apr 16, 2018
@solomonxie solomonxie changed the title Network Troubleshooting 网络故障排除 Network Engineering & Troubleshooting 网络工程师及故障排除 May 25, 2018
@solomonxie solomonxie changed the title Network Engineering & Troubleshooting 网络工程师及故障排除 Network Engineering 网络工程师 May 25, 2018
@solomonxie
Copy link
Owner Author

solomonxie commented May 25, 2018

❖ SMTP协议

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议。

邮件协议的理解

首先要理解邮件传输的流程。一直以来都有个大误会:以为是别人从他的电脑直接给我的电脑上发邮件。其实真的不是。真实流程和上网浏览网页是一模一样的。来重现一下打开网页的技术流程:

你向网站发出一个request请求,网站答应后发个你一个response网页HTML,然后你就可以看到网页了。

邮件也是一样的。
比如你要给Jason发邮件,他的邮箱是Gmail的。那你就向Gmail发送一个request请求,包括了收件人是谁、内容是什么。然后Gmail就在那里等,等Jason去Gmail查邮件的时候,就告诉他谁给他发了什么邮件。

Push Mail真的只是错觉。真的不是别人推送到你手机上或电脑上,只是它们在背后默默地每几秒钟就发送个request到服务器,去申请回应。就像浏览网页一样。

理解了这点,协议就基本上明了了。然后编程发邮件就变得简单起来。

Repository owner locked as off-topic and limited conversation to collaborators May 29, 2018
@solomonxie
Copy link
Owner Author

solomonxie commented Jul 22, 2018

国内的网站经常缺乏样式、无法下载css等文件

不管怎么设置proxy,就连关闭了proxy、关闭了adblock,国内网站如简书、豆瓣等大站,也经常显示不出来样式。查看chrome dev tool后发现,是他们使用的一些cdn完全无法连接。
然后尝试了解析那些cdn站的ip,并加到本地hosts里面。但是也没用。

然后怀疑是我使用的DNS出了问题。因为我本地网关(路由器)使用的是默认的小区宽带的默认DNS,不知道是哪里的。那个DNS很有可能功能出问题,导致很多网站的解析不正确。所以,我就把路由器里的DNS(或本机的DNS)设置为国内最好用的114.114.114.114

然而:并不管用。

@solomonxie
Copy link
Owner Author

solomonxie commented Jul 28, 2018

❖ Netdata 最帅Linux系统监控工具

一直在找方便的监控Linux系统状态和网络进出的,试了很多种都各有优缺。只有Netdata是安装最简单、显示最好看、最全面的监控工具。

注意,安装后会严重影响服务器运行速度,且默认安装的话安全性很低(默认没有密码,默认端口访问可以直接看到全部系统信息)

参考GIthub: Netdata

用脚本安装:

# 基本安装(适合所有Linux系统)
$ bash <(curl -Ss https://my-netdata.io/kickstart.sh)

# 或者从头安装(安装所有依赖包)
$ bash <(curl -Ss https://my-netdata.io/kickstart-static64.sh) 

脚本会检测当前系统环境,然后从头编译安装软件。

或者通过报管理器安装(目前各种包管理器的支持还不是很全):

  • Arch Linux (sudo pacman -S netdata)
  • Alpine Linux (sudo apk add netdata)
  • Debian Linux (sudo apt-get install netdata)
  • Gentoo Linux (sudo emerge --ask netdata)
  • OpenSUSE (sudo zypper install netdata)
  • Solus Linux (sudo eopkg install netdata)
  • Ubuntu Linux >= 18.04 (sudo apt install netdata)
  • MacOS (brew install netdata)

安装大概占用28MB空间。

根据提示,netdata会在这些位置安装文件:

image

安装好后,就可以直接打开浏览器:localhost:19999看到超酷的画面了(网页很长,显示超多数据)。

image

Netdata在安装后,主要是作为服务运行的。

开关控制:

# 启动:位置根据系统会有不同。建议加上-D参数前台运行,不要后台运行
$ sudo netdata -D
$ 或
$ sudo /usr/sbin/netdata -D
# 或(Mac上)
$ sudo /usr/local/sbin/netdata -D

# 关闭(方法很多种,往往只有一种生效)
$ sudo killall netdata
#
$ sudo pkill -9 netdata
#
$ sudo service netdata stop
#
$ sudo /etc/init.d/netdata stop
#
$ sudo systemctl stop netdata

卸载:

# 找到卸载脚本位置(我的在/usr/src/netdata.git)
whereis netdata.git
#  进入那个位置
cd /usr/src/netdata.git
# 开始卸载
yes | sudo ./netdata-uninstaller.sh --force
# 删除其它遗留信息
sudo userdel netdata
sudo groupdel netdata
sudo gpasswd -d netdata adm
sudo gpasswd -d netdata proxy

卸载其它被安装的软件:

yes | sudo apt-get purge ntop snapd

使用感受

网页浏览庞大精确系统信息的确很爽。
但是!
严重影响服务器速度!长期占用10%内存和很高的CPU。
而且还发现Netdata为了监控,还安装了很多其它软件,长期在后台运行。
甚至严重到影响SSH的延迟,ssh进去后打字反应都很慢。
所以没办法就卸载了。

卸载Netdata软件本身,和其它被这个安装的大量占用内存CPU的后台驻留软件后,重启服务器,又恢复了以前的速度。

更新

近期Netdata在Reddit上发布了v1.12更新。
由于我在下面发了回应说了下自己不好的感受,引发了主创者的质疑。
下面是链接:
https://www.reddit.com/r/docker/comments/as08my/netdata_the_opensource_realtime_performance_and/egs8ljq

意思是:我认为我在AWS上的实例因为安装了Netdata监控,而占用了大量CPU和内存,导致SSH连接操作速度下降,所以卸载了Netdata。但是主创者认为Netdata不可能导致这个后果。

所以我又再一次安装了Netdata,下面是内存占用的截图:

xnip2019-02-19_17-15-31

这个是从Netdata的Dashboard从查看的应用CPU占用:

xnip2019-02-19_17-31-41

这个是从Netdata的Dashboard从查看的应用内存占用:

xnip2019-02-19_17-33-18

这个是从Netdata的Dashboard从查看的应用进程占用:

image

可以看到,各项应用占用,netdata都排在第一。
但是这次SSH到远程主机,并没有以前感受到的那种延迟,操作也没什么反应。
发现也许是我当时的网络“受污染”导致的速度减缓,可能和Netdata没什么关系。

当时卸载的原因就是各项它都排第一,所以认为是它导致的。

@solomonxie
Copy link
Owner Author

solomonxie commented Sep 7, 2018

@solomonxie
Copy link
Owner Author

solomonxie commented Nov 14, 2018

查看所有与本机连接的网络客户端IP

假设自己是Server,想知道当前有多少人正在与自己连接,每个人的IP是什么。

Netstat:

$ netstat -pant

持续监视(利用watch命令):

$ watch netstat -pant

注意:Mac上默认版本非常低所以不兼容同样的参数,需要更新Mac的gnu utils等。
另外,watch需要额外brew安装

旧版本的用法如下:

$ watch netstat -ptcp -a

@solomonxie
Copy link
Owner Author

solomonxie commented Nov 15, 2018

❖ 理解子网掩码 Subnet Mask

网络掩码的唯一目的是:在一串IP中,区分哪部分是网络号,哪部分是主机号

一般在家里局域网中,假设我自己的电脑IP是192.168.1.123

  • 网络号就是192.168.1,即一台路由器所负责的“区域”,这片区域最多能有253台机器。
  • 主机号就是123,就是253台机器中的一台。

如果要达到通过IP传输,就必须先找到网络,再找到主机
然而,光是一串数字192.168.1.123,完全看不出哪部分是网络哪部分是主机。
这时候就必须要借助子网掩码。如果没有子网掩码,就不能实现通讯。

可以想象子网掩码是一个真的Mask面具:
假设IP写在一张纸上,而Mask是另一张用剪刀挖出一个窟窿的纸,然后把它盖在IP纸上,透过窟窿漏出来的那部分就是主机名

那么,通过编程怎么实现这个"面具"呢?
这是一个非常精妙的实现:把Mask也设置为一串看似IP地址的数字,然后通过IPMask转换成二进制,并进行逐位OR计算

计算过程:

  • 假设IP地址是:192.168.199.123, 子网掩码是255.255.255.0
  • 那么Mask中的255二进制化后变为1111 1111,那么IP中所有二进制数与它按位OR计算的结果,都是原数本身
  • 但是Mask中的0转换为二进制后是0000 0000,那么IP中的所有二进制数与它按位OR计算的结果,都是0.
  • 全部计算完毕后,结果再转换回十进制后是:192.168.199.0
  • 因为IP地址中,不能有主机名为0,所以这个结果中所有标记为0的部分,就指代为主机号范围了。

@solomonxie
Copy link
Owner Author

solomonxie commented Nov 15, 2018

❖ 一文入门跨平台的fswatch+rsync同步备份

rsync是非常好用,但是只是极好的cp而已。如果要监控本地某些文件变化,自动上传,还需要配合其它监控工具。一般都叫watch, notify什么的。
最有名的是inotify。但是inotify是linux内核的东西,没法在Mac上运行。
Mac上的替代方案是fswatch,而且可以跨平台运行(但是目前发现只有mac支持的最好)。

fswatch意料之外的简单好用,不需要配置文件,不需要复杂的参数,几分钟的学习就能完成一个真正可行的自动备份脚本,实际上作为“替代品”,远比inotify等要好用很多。在其Github官方说明上,也例数了当前最常用的各种inotify、kqueue等的缺点。

参考GIthub官方网址:https://github.com/emcrisostomo/fswatch

image

安装 (Mac):

$ brew install fswatch

使用,先直接输入命令试试:

# 开始监控(进入block堵塞模式,动态输出变动)
# 假设监控/tmp文件夹
fswatch -0 /tmp | while read -d "" event; do
    echo "This file ${event} has changed."
done

然后随意往/tmp文件夹创建个文件什么的: touch /tmp/000000.txt

这时候,刚才正在监控的shell,就会立马显示出新创建的文件名/tmp/000000.txt

利用fswatch+rsync备份

假如要监控/path/to/source/文件夹,那么就:

fswatch $1 | while read -d "" event; do
    rsync -rauv --delete --progress /path/to/source/ /path/to/target/
done

但是fswatch默认会进入堵塞模式,也就是一直挂在shell中。
如果我们让它后台运行,只需要在done后加一个&,转入后台运行即可。

多路径备份

虽然fswatch能够同时监控多个目录:如fswatch [options] ... path-0 ... path-n,但是一般我们是针对每个不同的文件夹做不同的事。
所以,最简单最方便的方法,就是同时运行多个fswatch

但是默认一个fswatch就进入堵塞模式,所以必须每次结束后转入后台,如done &

直接创建一个脚本rsync.sh,输入代码如下:

# 任务1
fswatch $1 | while read -d "" event; do
    rsync -rauv --delete --progress /path/to/source1/ /path/to/target1/
done &

# 任务2
fswatch $1 | while read -d "" event; do
    rsync -rauv --delete --progress /path/to/source2/ /path/to/target2/
done &

这样一来,我们不需要利用crontab来定时执行了。取而代之的是fswatch每次监控到变化就自动执行其中的语句。

至于fswatch的实现原理,这要涉及到Kernel内核的多任务运行机制。比如cron job是采用定期循环式运行一个任务,但是fswatch是采用消息通知式,有变化才运行任务。

要了解更多原理,就去查epoll异步IO等相关话题。这里,只知道怎么用就好了。

@solomonxie
Copy link
Owner Author

solomonxie commented Nov 26, 2018

❖ SSH 工具集 [DRAFT]

SSH程序,如OpenSSH,都会包含一系列的工具如:

  • sshd 服务端守护进程: 供别人登录本机
  • ssh 客户端连接程序:用来登录连接另一台电脑
  • ssh-keygen:密钥对生成工具
  • ssh-copy-id:把本机公钥上传到另一台电脑
  • ssh-agent:管理本机的私钥,并记住私钥的密码,省去每次输入的麻烦
    • ssh-add:把本机的私钥加入到ssh-agent的管理之中

也就是说,只要本机装了SSH,就自动包括了这些工具,无需额外安装。

ssh-keygen

非常简单的小命令,什么参数都不用输,一路按回车就能生成一对本机的密钥对。
在默认情况下,会生成一个没有pass_phrase密码的密钥对,都在~/.ssh/目录下,一个id_rsa私钥,一个id_rsa.pub公钥。

如果需要对密钥对加上密码保护(pass_phrase),在交互过程中,可以输入,很简单。

关于生成密钥对,还有一些其它选项:
...

ssh-copy-id

是个极其方便的小命令,即把本机~/.ssh/目录下的所有public公钥写入到指定服务器上的~/.ssh/authorized_keys文件中。比起以往自己手动复制本地的公钥然后ssh进入服务器用vim打开autorized_keys粘贴,这个命令一步到位,很方便。

命令很简单:

$ ssh-copy-id 用户名@服务器地址

不加任何参数,命令就会把本机~/.ssh/目录下所有公钥上传上去。
如果要手动指定,则用-i指令:

$ ssh-copy-id -i /path/to/public_key

ssh-agent

简而言之,ssh-agent会管理本机的私钥,并记住私钥的密码,省去每次输入的麻烦。
它不是默认启动的,如果我们启动它,就会开启一个daemon守护进程,不间断运行以帮助我们免密码并安全的登录各种远端服务器。

ssh-agent这个命令的本质,实际上只是修改几个环境变量,打印出一个进程ID。所以我们不能直接运行,而是要用eval命令来运行它。

image

主要步骤有两步:

# 开启ssh-agent守护进程 (使用反引号)
$ eval `ssh-agent`

# 将默认私钥(~/.ssh/id_rsa) 添加到agent管理之中
$ ssh-add

# 或,将指定私钥加入管理
$ ssh-add /path/to/key

# 关闭agent
pkill ssh-agent

这就完成了!

明明已经有了一对密钥,为什么还需要ssh-agent?

密钥对对问题是,一个不小心,把私钥的这个小文本文件泄露到不该泄露的地方,就一切防御都化为虚有了,供人随意出入。所以一般要对这个小文本文件本身再有一个加密才安全。
但是很多时候使用密钥对,就是为了省去输入密码的麻烦,这就不高兴了,所以才有了ssh-agent。
它让你只在本机中有个小管家,代替你输入pass_phrase密码来使用私钥。这样即使别人窃取了你的私钥小文本文件,也没用。

所以ssh-agent是个逻辑问题,程序本身倒是没什么很值得研究的。

@solomonxie
Copy link
Owner Author

solomonxie commented Nov 27, 2018

❖ Webdav (Apache) 的文件权限问题

Apache的Webdav实现是目前最稳定最完善的,所以这里就只讲Apache版本的问题。

这个实现最主要混淆的地方,就是文件权限问题。即我们默认赋予了webdav共享文件夹www-data用户和用户组,这样就导致普通用户没法正常在上面创建文件,必须用sudo才行。
或者我们直接把webdav文件夹权限组设置为me:me这样的纯属于本用户的权限,可是会导致网络无法发现或无权读写。

如果再加上是跑在docker容器里的apache版Webdav,那么问题就更复杂一步了:docker里面和host主机上分别怎么对同一个文件夹设置权限组?
尝试了很多种配合组合,都不太满意,总是有问题。

Stackoverflow了一下发现最简单的解决方案:
(如果涉及docker,无需到容器里面改权限,全部在host主机上改即可)

sudo chown -R YOURNAME:www-data /var/www/webdav
sudo chmod -R g+s /var/www/webdav

这种做法是,把webdav文件夹的权限设为当前用户+www-data组。然后为组加上g+s,这样新创建的文件就会自动刚刚设置的www-data组的id了。

For a directory, g+s overrides the group id that new files and directories will have (it is usually inherited from the creator).

@solomonxie
Copy link
Owner Author

solomonxie commented Dec 6, 2018

❖ 理解Virtualbox虚拟机的四种网络连接方式 [DRAFT]

参考:快速理解VirtualBox的四种网络连接方式
参考:VirtualBox中ubuntu的网络设置

Virtualbox连接网络一共有四种方式(其它虚拟机也都差不多一样的称呼):

  • NAT
  • Bridged Adapter
  • Internal
  • Host-only Adapter

image

image

image

image

最好用的是Bridge方式
可以满足虚拟机中的所有网络需求,通过使用host主机的网卡,直接连到host网络,此时的虚拟机就和真正的机器一样.虚拟机可以访问外网,可以访问host主机.host主机也可以访问虚拟机.

但是:

如果是我们使用的无线网,或者我们没有任何路由器,只是在本机无网络的情况下开发呢?我们就需要使用仅主机模式了

@solomonxie
Copy link
Owner Author

solomonxie commented Dec 6, 2018

❖ Virtualbox连接网络设置

需求一:让虚拟机又能访问外网又可以与主机对话

参考:VirtualBox: 为你的虚拟机配置静态 IP

这就是需要用到Virtualbox 双网卡适配器。
因为要满足虚拟机能访问外网,又能与主机沟通,就需要两块网卡。所以我们要在Virtualbox中给它设置两个Adapter(网卡),然后设置为:

NAT + Host-only

首先在Virtualbox软件的全局设置

image

设置DHCP(这样虚拟机就能有静态IP了):
image

然后设置虚拟主机

首先要在虚拟主机关闭的情况下设置。

开启2个Adapter:NAT和Host-only

NAT适配器采用默认设置:
image

Host-only设置:
image

然后进入虚拟机(Linux)后,就可以通过ifconfig看到本机的内网IP了。

image

可以在自己的Host机子上ping一下这个虚拟机,发现可以ping通。

反过来,在虚拟机里ping一下Host(刚才设置全局的一个内网时候的192.168.56.1就是)。

需求二:让虚拟机又能访问外网又在Wifi同网段

和需求一差不多,这里只做简单的改变:
双网卡设置为:

Bridge + Host-only

其中Bridge设置如下:

image

进入虚拟机后,输入命令ifconfig就会发现,虚拟机具有了和我的主机在Wifi里同样网段的IP地址(我的wifi网段是192.168.199.xxx):

image

@solomonxie
Copy link
Owner Author

solomonxie commented Dec 9, 2018

Shadowsocks-libev安装

Shadowsocks服务器分为很多版本,每个版本都同时包含server和client等程序,每个版本所使用的JSON配置文件也都完全一样。不同的只有启动方式、速度、体积、网络处理方式等等。

ss-libev这个版本是C语言写的,体积小速度快。

安装

Ubuntu / Debian / 树莓派等安装方法:

sudo apt-get install -y shadowsocks-libev

如果一些平台不支持,则需要自行编译,但是不推荐。
Debian系编译方法如下:

# Dependencies
yes | sudo apt-get install --no-install-recommends gettext build-essential autoconf libtool libpcre3-dev asciidoc xmlto libev-dev libc-ares-dev automake libmbedtls-dev libsodium-devA && \
echo "[OK]"
mkdir -p ~/local/build_source/
cd ~/local/build_source/
# Installation of libsodium
export LIBSODIUM_VER=1.0.16
wget https://download.libsodium.org/libsodium/releases/libsodium-$LIBSODIUM_VER.tar.gz && \
tar xvf libsodium-$LIBSODIUM_VER.tar.gz && \
pushd libsodium-$LIBSODIUM_VER && \
./configure --prefix=/opt && \
make && sudo make install && \
popd && sudo ldconfig && echo "[OK]"
# Installation of MbedTLS
export MBEDTLS_VER=2.6.0 && \
wget https://tls.mbed.org/download/mbedtls-$MBEDTLS_VER-gpl.tgz && \
tar xvf mbedtls-$MBEDTLS_VER-gpl.tgz && \
pushd mbedtls-$MBEDTLS_VER && \
make SHARED=1 CFLAGS=-fPIC && \
sudo make DESTDIR=/opt install && \
popd && sudo ldconfi && echo "[OK]"

git clone https://github.com/madeye/shadowsocks-libev.git
cd shadowsocks-libev
git submodule update --init --recursive
# Start building
./autogen.sh && \
./configure --prefix=/opt/shadowsocks-libev  && \
make && sudo make install && \
echo "[ OK ]"

这个编译步骤目前没法保证都能成功,还要仔细研究。。。

配置

配置文件和一般都ss-local方法一样。

shadowsocks-libev的配置文件一般位于:/etc/shadowsocks-libev/config.json
内容参考如下:

{
    "server":"My-Server-IP-Address",
    "server_port": 8888,
    "local_port": 1080,
    "password":"password123",
    "method":"aes-256-gcm",
    "timeout": 10
}

启动停止方法

和其它版本不同,这个版本比较好操作:

客户端:

# 前端启动(无需多余参数),停止的话直接Ctrl+C
$ ss-local

# 以后台服务启动

@solomonxie
Copy link
Owner Author

Linux命令行FTP客户端

FTP

Ubuntu安装:

$ sudo apt-get install ftp

使用:

ftp <URL> 

ftp> ls
ftp> cd <path>

# 设置下载至的本地文件夹
ftp> lcd /home/Jason/ftpshare
ftp> get <FILE NAME>

curlftpfs

将FTP映射为本地文件夹,正常操作。

Ubuntu安装:

$ sudo apt-get install curlftpfs

# 挂载
$ mkdir ~/ftpshare
$ curlftpfs <URL> ~/ftpshare

# 解除挂载
sudo umount ~/ftpshare

@solomonxie
Copy link
Owner Author

solomonxie commented Dec 23, 2018

❖ HTTP 的重定向

一直好奇,当我们request一个URL时候,它是怎么在后台就转向了。
浏览器是接收到什么指令了才会被重定向?在Headers中?在文档中被JS脚本重定向?还是什么?

参考Mozilla超好看文档:HTTP 的重定向

也就是说,命令客户端的浏览器对一个URL重定向的方法有:

  • (*) 通过Status Code+Headers: Location来命令浏览器重定向至Location的网址
  • HTML的头部的<meta>标签中设置重定向。但是只适用于HTML,类似图片等其它资源就不行了
  • Javascript脚本中写window.location="..."重定向。同样只适用于能加载JS的客户端,不适合其它资源。

通过Status Code状态码重定向

这种方法是最标准、适应度最广泛的:也就是无需HMTL,无需浏览器,无需BODY,只要Headers即可要求接收者重定向。

原理图:

image

要求重定向的状态码有:

  • 永久重定向
    • 301
    • 308
  • 临时重定向
    • 302
    • 303
    • 307
  • 特殊重定向
    • 300
    • 304

Python获取每次重定向的地址

一般来说,我们用requests的方法,

r = requests.get(uri, allow_redirects=True)
print( r.url )

for jump in r.history:
    print( jump.url )

但是最近在使用一些WebAPI时候,如Oauth2.0的时候,只有登录后才会重定向。
所以如果程序中没有做到登录,后台就不会重定向。也就是说,request的时候我们要加入cookies登录信息,而且是对应着最开始response中的set cookies设置的cookies才能被重定向。

@solomonxie
Copy link
Owner Author

solomonxie commented Dec 23, 2018

❖ Session & Cookies [DRAFT]

DRAFT

  • Cookies -> Mini K-V Database on client side, then server becomes visitor
  • Session -> A specific row of data in the “Cookies DB”

Session is just a value of sessionID, as a temporary REFERENCE to userID.

Reasons of using session:

  • Identify the client’s userID without exposing it
  • Check login status of a user:
    • client has sessionID: logged in
    • Doesn’t have: not logged in

Session storage:

  • On server, AND
  • On client, as a cookie

@solomonxie
Copy link
Owner Author

solomonxie commented Dec 26, 2018

❖ Is socket a file? [DRAFT]

Yes, socket IS a file!

Refer to: Is there a file for each socket?

image

Where is the file for each socket?

@solomonxie
Copy link
Owner Author

solomonxie commented Jan 29, 2019

Linux挂载Webdav共享文件夹 (davfs2) [DRAFT]

参考:Ubuntu 16.04: Install davfs2 for WebDAV client

需要用到davfs2这个程序。

Ubuntu、树莓派安装:

$ sudo apt install davfs2 -y

# 进入交互
#。。。

# 或者设置默认选项,免交互安装:
cat <<EOF | sudo debconf-set-selections
davfs2 davfs2/suid_file boolean false
EOF
sudo apt install davfs2 -y

挂载远程Webdav共享文件夹:

$ sudo mount -t davfs "地址" /path/to/mount/point/
# 然后进入交互,输入用户名和密码
# ...
# OK完成挂载

完成挂载后,就可以像正常访问本地文件夹一样在命令行里操作了。

在fstab中设置自动挂载

安全的记住密码自动登陆

davfs2体验

虽然直接把webdav共享文件夹映射为本地磁盘/文件夹用起来很方便,但是缺点也和其它所有把网盘映射为文件系统的程序一样很明显:速度太慢!而且卡顿起来会把整个系统都卡住!别的什么事都做不了。

@solomonxie
Copy link
Owner Author

solomonxie commented Jan 30, 2019

Webdav的命令行客户端体验 [DRAFT]

支持Webdav的GUI客户端实在太多了,不说Windows和Mac的原生支持,还有各种Cybderduck等软件也支持。
但是当我们需要让远程服务器24小时运行任务同步时,GUI界面就不管用了,只能用命令行。

目前收集的主流命令行客户端如下:

Cadaver:类似ftpsmbclient的shell操作客户端

Cadaver的特点是需要进入特制的shell,在特制shell里面输入命令执行上传下载等操作,而不能直接通过命令行的cadaver命令进行这些操作。整体和常用的工具ftp,smbclient类似。

参考: Using Cadaver as a WebDAV Client
参考:cadaver - Linux Man Pages

Ubuntu安装:

$ sudo apt-get install cadaver

使用:

# 连接
$ cadaver http://example/webdav/path

# 进入交互,输入用户名密码
# ...

# 进入cadaver的shell
dav:/

# 输入命令
# ...

常用命令:

  • ls:显示当前路径文件
  • cd:进入子目录
  • cd ..:返回上层文件夹
  • get remote/path local/path:下载远程文件至本地
  • put local/path remote/path:上传本地文件至远程
  • mget name*:根据匹配名称,下载多个文件

cadaver 体验

个人不是很喜欢ftp/cadaver等这种进入shell操作的体验,不能自动补全命令,没有bash或zsh好用,而且过于手动化了,控制性不强。
速度和传输实时进程的显示还不错,只是太不方便了。

rclone:超强大的网盘同步工具

rclone是非常强大的云盘同步工具,支持相当多种类的云盘传输同步:AWS S3, AWS Drive, Dropbox, FTP, Google Drive, Yandex Disk等等数十种。

官方标语是:

rclone is rsync for Cloud Storage.

参考:WebDAV - rsync for cloud storage.

rclone安装比较简单,不需要额外以来,直接到官网下载压缩包,把里面的二进制主程序rclone复制到本地类似/usr/local/bin到地方就可以运行。只是下载的时候要区分本机的OS和CPU架构。

比如Mac就下载rclone-current-osx-amd64.zip,Linux就下载rclone-current-linux-amd64.zip,树莓派就下载rclone-current-linux-arm64.zip

官方下载列表:https://downloads.rclone.org/

# Download and install to sbin
wget https://downloads.rclone.org/rclone-current-linux-arm64.zip && \
unzip rclone-current-linux-*.zip && \
sudo cp rclone-*/rclone /usr/sbin/ && \
rm -r rclone-*/

# Give proper permissions
sudo chown $USER:$USER /usr/sbin/rclone
sudo chmod 755 /usr/sbin/rclone

测试:rclone --version
如果出现错误exec format error: rclone,则说明对应的os和架构版本没有正确下载。

以上把rclone这个文件放到任意/bin目录下就算安装完成了。直接执行rclone命令即可。但是使用之前还要配置具体网盘信息才行。

创建网盘

因为不像rsync比较单纯通过ssh传输,rclone支持各种完全不同的网盘,所以在正式传输之前,必须针对指定的网盘进行用户名密码等配置才能开始传输。

输入rclone config命令,进入交互式的设定。设定的主要做的就是添加网盘

如果是添加Webdav网盘的话(Dropbox等这里先不讲),执行命令顺序如下:

  • n/s/q> 处,输入n,即添加新网盘
  • name> 处,随便起个网盘的别名,比如my-webdav,之后传输时候会用到
  • Storage> 处,选择网盘类型,这里选24,即webdav
  • url> 处,输入webdav的http网址,如http://example:1234/webdav/
  • vender> 处,选4,即other software。
  • user> 处,填用户名
  • y/g/n>处,选y,即手填密码,然后输入密码2遍。
  • bearer_token> 处,不填,直接回车。
  • y/e/d> 处,选y,确定创建网盘。

现在创建好了网盘,就会显示出现存的所有网盘:

image

rclone基本操作

列出网盘中目录(lsd命令):
rclone lsd my-webdav:/

记住要在网盘别名后加:/目录路径。

列出网盘中某个子目录下的文件(ls命令):
rclone ls my-webdav:/sub/sub/

注意:ls命令会用递归显示处所有子目录和子子目录中的文件。

rclone传输

传输主要是用了rclone的sync子命令。

远程与本地:

# 下载
$ rclone sync my-webdav:/folder /home/me/folder

# 上传
$ rclone sync /home/me/folder my-webdav:/folder

两个网盘之间互传:

$ rclone sync my-webdav:/folder my-dropbox:/folder

注意:默认传输是没有任何进度显示的。如果文件量大,会导致数个小时毫无任何信息输出,以为程序卡住了。所以要加上-P参数带实时进度传输:

$ rclone sync -P src:/ dst:/

image

rclone的命令

参考:Rclone Commands
参考:Rclone: 超好用的网盘 / VPS 数据同步、备份工具,支持 Google Drive

除了lssync外,还有支持所有基本的命令。

  • rsync delete remote:/path,删除
  • rsync move remote:/path,移动
  • rsync copy src:/path dst:/path,复制
  • rsync purge remote:/path,清空目录下所有文件
  • rsync mkdir remote:/path,创建文件夹
  • rsync check src:/path dst:/path,检查两个网盘间的目录是否完全相同
  • rsync size remote:/path,计算占用大小

image

rclone的持久化配置

rclone的体验

体验如下:

  • 网盘添加及其简单
  • 如cp/mv一样简单的上传下载同步
  • 直接的网盘间互传
  • 实时速度显示
  • 传输速度比davfs2快很多倍
  • 不像其它FUSE文件系统映射一样影响系统运行

光这几点,就已经超过了很多GUI客户端应用了。
无论从各方面来看,rclone已经可以达到或超越桌面GUI客户端Cyberduck的使用体验了。

@solomonxie
Copy link
Owner Author

❖ HTTP协议入门 [DRAFT]

注意事项:

  • Browser区分Response回复的Header和Body的方法:Header各个值之间是紧凑的,一旦遇到空行,则视为开始Body内容。所以Body一定要与Header内容空开一行!

HTTP协议的1.0与1.1的版本对比

  • HTTP/1.0: 采用短连接,即Client的每次请求都需要建立一次连接,即每次都重新三次握手、四次挥手,才能提出请求、得到数据。
  • HTTP/1.1: 采用长连接,即Client在一定时间内,只建立一次连接,完成三次握手后可以进行多次请求和数据传输。

短连接、长连接,指的是一次连接的时长、或一次连接能完成的请求次数多少。

一个网站页面往往包括HTML、多张图片等资源,如果仍然使用短连接,那么光一个网页加载就需要占用服务器多条进程或多条线程或协程,那么对服务器的开销就太大了。

image

如何做到长连接?很简单,只要在HTTP headers中设定请求HTTP/1.1即可。这样服务器在发送完数据后,不会马上断开连接,而是等待下一个请求,直到超时或客户端主动发来断开连接的请求。

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 15, 2019

❖ 网页视频流HLS 格式(m3u8/ts)视频下载

现在很多视频网站播放流视频,都不是采用mp4/flv文件直接播放,而是采用HLS(m3u8/ts)这种方式播放。

简单说就是,网站后台把视频切片成成百上千个xx.ts文件,一般10秒一个,每个都几百kb很小。然后通过xx.m3u8播放列表把这些文件连接起来。

通过Chrome DevTool的Network栏,我们可以清楚的看到加载过程:

image

我们直接点击这个playlist.m3u8播放列表文件,在旁边的preview栏中查看内容,可以看到:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:11
#EXTINF:5.250000,
out000.ts
#EXTINF:9.500000,
out001.ts
#EXTINF:8.375000,
out002.ts
#EXTINF:5.375000,
out003.ts
#EXTINF:9.000000,
out004.ts
...........

那我们怎么下载呢?

下载视频所有的ts切片文件

一般的思路是,想办法把所有的ts切片文件下载下来,然后合成一个完整的视频。
然而,配合xx.m3u8播放列表文件,我们可以直接用ffmpeg在线下载播放列表中所有的视频,然后直接用ffmpeg合并为一个视频。

我们就直接执行这一句命令即可:

$ ffmpeg -i <m3u8-path> -c copy OUTPUT.mp4
$ ffmpeg -i <m3u8-path> -vcodec copy -acodec copy OUTPUT.mp4

# 例如:
ffmpeg -i https://v6.438vip.com/2018/10/17/3JAHPTdvPhQb9LrE/playlist.m3u8 -c copy  OUTPUT.mp4

然后就会看到这样的下载过程:

image

为什么下载播放列表就能下载所有的切片文件?
因为播放列表里的都是相对路径,既然我们有了播放列表的绝对路径,那么其它所有文件的绝对路径也就不难获取了。
好在ffmpeg直接实现了这种播放列表一键下载的方式。

必须登录的视频下载

ffmpeg不支持cookies,所以如果视频网站需要登录才能看,那么ffmpeg就无能为力了。
这种时候,有两种解决思路:

  • HLS视频流捕获的Chrome插件
  • 根据播放列表手动整理所有ts文件的下载连接,用wget/curl加cookies下载。

Chrome插件下载HLS流视频

目前推荐的Chrome插件有:

Chrome插件因为是在浏览器里的,所以直接可以获取cookies和user-agent,只要自己能看,插件就能下载。

Wget/Curl下载HLS流视频

简单来说,就是把xx.m3u8播放列表下载,然后从里面抽取所有的文件名称,并在前缀加上完整的URL链接,然后用wget/curl以下载文件列表的方式批量下载。最后用ffmpeg合并所有视频文件。

@solomonxie
Copy link
Owner Author

What is CSRF (Cross Site Request Forgery)

Refer to: Cross Site Request Forgery - Computerphile

The attack is to make your own web page including a hidden <form> that includes your id, password or any other necessary information, and when a user open this malicious page it'll submit the form to the original site, say your bank site, and do something you unexpected.

Usually it won't work because the HTTP asks to have a referrer in each request's header, so that the "bank" will notice the request is not from the "bank"'s page but your malicious fake page.
But the thing is, in the modern network that there's private mode or adblocker in the browser that stops including the referrer in header of your request, so that the "bank" wouldn't know where's the request comes from & wouldn't stop you to login just because you're in private mode.
This allows the CSRF to work like what's described above.

How to stop that request from other sites if they don't have the referrer in header?
That solution is to add a random token in each form of the "bank"'s site. Any user opens up a page from the "bank", it'll generate a token hidden in the form, and it'll be changed each time you refresh the page as well.
So the attacker is not possible to fake that token in their own malicious web page. Because when you send a token made by yourself and send to the "bank", they'll decode it and find out that's not what they have generated and notice that this request is not from the official website.

And here comes the brief summary:
The CSRF protection is simply to add a random token in each form that only the server can understand, which stops requests from other sites.

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 9, 2020

利用Haproxy实现Shadowsocks负载均衡 [DRAFT]

  • 在家里树莓派上安装Haproxy作为前端入口,然后把流量分发给各个后端SS主机

树莓派本地Shadowsocks-client客户端安装与配置

# 这样可以安装到最新版本,有更多的加密算法。直接用pip装可能只支持很低的版本
$ sudo pip install https://github.com/shadowsocks/shadowsocks/archive/master.zip

# 创建客户端配置文件(自行操作)
$ touch ~/ss-local.json
$ vim ~/ss-local.json

客户端配置(注意local地址必须是0.0.0.0这样才能收到来自局域网的请求):

{
    "server":"服务器公网地址",
    "server_port": "服务器端口",
    "local_address":"0.0.0.0",
    "local_port":1080,
    "password":"ss密码",
    "timeout":600,
    "method":"加密方式"
}

开启客户端,也就是允许转发:

# 手动启动客户端
# 在未确定是否能联通之前,最好先用这种方式,显示输出连接信息

$ sslocal -c ~/ss-local.json -v

# 在命令行中验证
$ export all_proxy=socks5://0.0.0.0:1080
$ curl http://httpbin.org/ip
{
  "origin": "此处如果显示的是服务器地址就对了,如果是本机地址就没生效"
}

sslocal报错:Unsupported SOCKS protocol version 71

在调试期间,我们倾向于让sslocal在前台运行并加上-v参数输出所有连接信息。
这时候如果我们用curl去测试连接,会报出unsupported SOCKS protocol version 71这个错误。
如果用wget或浏览器等方式去连接,后面的version数字会不一样。

这个问题的本质不是ss的问题,而是连接一方的错误:

  • 如果在命令行连接,那么环境变量all_proxy应该设置为socks5://xxxxxx 而不是http://xxxx
  • 如果用浏览器或系统连接,那么protocol也应该设置为socks5而不是http
  • 如果想用http连接代理,那么应该用第三方软件去转发

image

sslocal 报错:libsodium not found

参考:https://github.com/RubyCrypto/rbnacl/wiki/Installing-libsodium

sudo apt-get install libsodium18

本地开启多个sslocal实例用来连接多台服务器


Haproxy安装与配置

参考:https://tianws.github.io/skill/2019/07/11/gfw/

$ sudo apt install haproxy -y
$ sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak # 备份
$ sudo vim /etc/haproxy/haproxy.cfg # 编辑配置文件

配置文件设置:

global
    log /dev/log local0
    log /dev/log local1 notice
    user root
    group root
    daemon

defaults
    log global
    mode tcp
    timeout connect 5s
    timeout client 5s
    timeout server 5s
    option      dontlognull
    option      redispatch
    retries     3

listen status
  bind *:1111
  mode  http
  stats refresh 30s
  stats uri /status
  stats realm Haproxy  
  stats auth admin:admin
  stats hide-version
  stats admin if TRUE

frontend shadowsocks-in
    mode tcp
    bind *:8388
    default_backend shadowsocks-out

backend shadowsocks-out
    mode tcp
    option      tcp-check
    balance roundrobin
    server  servername1    xxxxx1.com:8088  check
    server  servername2    xxxxx2.net:8080  check
    server  servername3    12.34.56.78:9999  check
    server  servername4    123.234.234.123:443  check

使用Haproxy:

sudo service haproxy start|stop|status|reload|restart|force-reload # 控制 haproxy 的运行

为了让haproxy更自由启动停止,我们可以屏蔽掉haproxy的service服务,这样就不会自动开机启动它:

sudo systemctl disable haproxy

Haproxy启动失败

# 启动
$ sudo service haproxy start
Job for haproxy.service failed because the control process exited with error code.
See "systemctl status haproxy.service" and "journalctl -xe" for details.

#检查日志
● haproxy.service - HAProxy Load Balancer
Feb 09 09:37:50 raspberrypi systemd[1]: haproxy.service: Unit entered failed state.
Feb 09 09:37:50 raspberrypi systemd[1]: haproxy.service: Failed with result 'exit-code'.
Feb 09 09:37:50 raspberrypi systemd[1]: haproxy.service: Service hold-off time over, scheduling restart.

从这里看不出什么,那就停止haproxy服务,然后用前台运行的方式来看看哪里出的问题:

$ sudo service haproxy stop
# -d表示debug模式,前台运行,-V表示增强输出信息
$ haproxy -f /etc/haproxy/haproxy.cfg -d -V
[ALERT] 039/093841 (4776) : Starting frontend shadowsocks-in: cannot bind socket [0.0.0.0:8388]

然后根据问题各种改配置就好了,比如端口被占用,就换端口,用户名不对,就改用户名等等。

image

Haproxy正常启动后,就会产生一个主页显示统计信息,可以从局域网访问本地IP地址:1111/status
image

(端口号和登录页面的用户名密码都是刚刚在配置文件里面配置的)

可选的负载均衡策略

balance roundrobin
balance url_param userid
balance url_param session_id check_post 64
balance hdr(User-Agent)
balance hdr(host)
balance hdr(Host) use_domain_only

但是这都不能保证可用性,即某一个节点掉线了的问题。这时候就需要再安装一个工具来进行健康检查

结合Keepalive做健康检查


将sock5流量转发为Http流量

即使很多程序直接连接socks5代理协议的端口,但还是没有Http协议的支持范围广,所以为了方便我们可以建立一个接收Http代理请求的转发器,把接收到的流量转发到sock5的端口。

最常用的转发器就是Privoxy.

参考:http://einverne.github.io/post/2018/03/privoxy-forward-socks-to-http.html

sudo apt-get install privoxy -y
# 修改配置文件
sudo vim /etc/privoxy/config

#/etc/privoxy/config
forward-socks5t / 127.0.0.1:1080 .
listen-address 0.0.0.0:1090
# 上面一定要用0.0.0.0,这样就可以接收局域网Http请求。然后把请求转发到本地的socks5接口

#停止后台自动启动的privoxy服务
sudo systemctl stop privoxy

#手动指定配置文件,并在前台启动 (利于debug和监测)
privoxy --no-daemon /etc/privoxy/config

尝试是否成功:

export http_proxy=http://127.0.0.1:1090
curl http://httpbin.org/ip

如果显示的IP地址,是之前为1080的socks5端口设置的IP地址,则正确完成了转发。

为了让Privoxy更自由启动停止,我们可以屏蔽掉Privoxy的service服务,这样就不会自动开机启动它:

sudo systemctl disable privoxy

使用Nginx代替Haproxy作为高可用负载均衡

Nginx比Haproxy具有更高的稳定性和功能扩展性。

实战证明:虽然Haproxy更容易配置,但是如果backend服务器都不是很稳定的情况下,丢包率严重(一个网页只能加载部分内容)。而且Haproxy对轮训的策略支持有限,对地理位置的访问限制也不支持。
另一方面,Haproxy的timeout设置非常tricky,所以导致可用的backend服务器不能有效利用,不可用的服务器反而被轮到。而Nginx会只连接一个backend可用的服务器来满足所有要求,当它不可用时候才断开连接使用另一个服务器。

sudo apt-get install nginx -y
# 查看nginx信息,确保具备 with-stream功能
nginx -V |grep with-stream

# 关掉默认开启启动的nginx服务,因为之后我们要手动在前台启动
sudo systemctl stop nginx
sudo systemctl disable nginx

# 备份nginx配置
cd /etc/nginx
sudo cp -a nginx.conf{,_$(date +%F)}

# 创建自定义配置(文件名必须一致)
sudo mkdir /etc/nginx/tcp.d
sudo touch /etc/nginx/tcp.d/openldap.conf

# 让Nginx主配置引用我们自定义的配置
sudo echo "include /etc/nginx/tcp.d/*.conf;" >> /etc/nginx/nginx.conf

# 编辑自定义配置
sudo vim /etc/nginx/tcp.d/openldap.conf

添加如下内容:

stream {
    upstream backend {
        hash $remote_addr;  #hash只是轮训的其中一种策略
        server 127.0.0.1:1081 max_fails=3 fail_timeout=10s;
        server 127.0.0.1:1082 max_fails=3 fail_timeout=10s;
        server 127.0.0.1:1083 max_fails=3 fail_timeout=10s;
        server 127.0.0.1:1084 max_fails=3 fail_timeout=10s;
    }
    server {
        listen 0.0.0.0:1070;  #对外暴露前台端口,必须是0.0.0.0才能接受本机之外的访问
        proxy_timeout 20s;
        proxy_pass backend;
    }
}

然后重启:

#重启前检查配置是否有写错的地方:
sudo nginx -t -c /etc/nginx/nginx.conf

#重启nginx
# sudo systemctl restart nginx

# 单独开一个shell,在前台运行nginx:
sudo nginx -c /etc/nginx/nginx.conf -g 'daemon off;'

#测试
telnet 0.0.0.0 1070

#正确的显示:
Trying 0.0.0.0...
Connected to 0.0.0.0.
Escape character is '^]'.

# 按Ctrl-] 推出telnet

能不能使用Nginx对某些地域IP进行屏蔽?

Nginx确实可以结合GeoIP来达到地域block屏蔽的效果,但是目前只针对HTTP一类的请求。对于tcp流量转发、反向代理这种,则无法做到。

如果真的在这个层面有屏蔽需求,那么可以直接用iptablesfirewalld在最底层进行拦截。

@solomonxie
Copy link
Owner Author

SSH 端口转发

本地端口转发: 从本地的一个端口转发到另一个接口

首先确认端口转发功能在配置里是开的:

sudo vim /etc/ssh/sshd_config

# 开启tcp转发
AllowTcpForwarding yes

# 重启sshd
sudo /etc/rc.d/init.d/sshd restart

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 14, 2020

简单方法理解Nginx反向代理

参考:https://www.zybuluo.com/orangleliu/note/478334

安装Nginx略过(要求版本1.9以上)。
配置:

sudo echo "include /etc/nginx/tcp.d/*.conf;" >> /etc/nginx/nginx.conf
sudo vim /etc/nginx/tcp.d/openldap.conf

配置里,我们将要让Nginx把7777端口作为对外暴露的前台端口,然后选用两个让后台服务器:即bash小程序nc制作的史上最简单的服务器。图例摘抄自上面的参考文章:

                          / nc -l 7773
telnet--> nginx(30003) -->
                          \ nc -l 7774

/etc/nginx/tcp.d/openldap.conf的内容是:

stream {
    upstream backend {
        server 127.0.0.1:7001;
        server 127.0.0.1:7002;
    }
    server {
        listen 0.0.0.0:7777;
        proxy_timeout 10s;
        proxy_pass backend;
    }
}

配置内容可以直接从字面理解。参考图例:

                       / host2(ss)
client --> host1(nginx) 
                       \ host3(ss)

重启nginx,让配置生效: sudo systemctl restart nginx

这时候,Nginx还没有接到任何请求,我们必须先把那两个“史上最简单服务器”建立起来以应付将来的请求:

# 单独开启一个shell来创建这个服务器:
nc -l 7001

# 再单独开启另一个shell作为第二台服务器:
nc -l 7002

然后用telnet假装一个外界来的访客,给Nginx暴露的前台端口建立连接、发请求:

telnet 127.0.0.1 7777

然后我们可以看到,第一个服务器7001先响应了。这时候可以假装在服务端(telnet)和客户端(nc)之间互相发消息了。

由于我们之前把前台端口暴露到0.0.0.0上了,如果想测试局域网或公网上是否生效,可以这样来发请求:

telnet 服务器公网IP地址:777

如果我们把telnet断开,再连一遍,会发现这时候7002响应了。也就是说Nginx把另一个连接自动配给下一个请求。

image

@solomonxie
Copy link
Owner Author

BBR锐速:升级Linux内核安装GoogleBBR的TCP算法

一般都是用一键安装脚本来安装。

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 14, 2020

Linux命令监控外来网络连接

netstat 命令

$ netstat -tencut

tcpdump 命令

ss命令

参考:https://www.binarytides.com/linux-ss-command/

$ ss -nt src :443 or src :80

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 15, 2020

Nginx及依赖库的编译安装

参考:https://segmentfault.com/a/1190000014783064
参考:http://nginx.org/en/docs/configure.html
参考:https://www.mgchen.com/251.html

安装顺序是:

  • 编译安装依赖
    • PCRE
    • OpenSSL
    • Zlib
  • 编译安装Nginx
    • 安装其它依赖库
    • 指定依赖库的路径时,不是指定安装位置,而是**源码位置**
cd /tmp

# 安装PCRE, 官方下载列表:https://ftp.pcre.org/pub/pcre/
# 注意:一定不要选PCRE版本2xx,因为会在nginx安装时候出错
wget https://ftp.pcre.org/pub/pcre/pcre-8.36.tar.gz
tar -xzvf pcre-8.36.tar.gz

# 安装OpenSSL, 官方下载列表:https://www.openssl.org/source/:
wget https://www.openssl.org/source/openssl-1.1.0g.tar.gz
tar -xzvf openssl-1.1.0g.tar.gz

# 安装Zlib, 官方下载列表:http://www.zlib.net/
wget https://downloads.sourceforge.net/project/libpng/zlib/1.2.11/zlib-1.2.11.tar.gz
tar -xzvf zlib-1.2.11.tar.gz

安装其它依赖包:

# GeoIP 模块
sudo apt-get install libgeoip-dev -y

#  HTTP XSLT 模块
sudo apt-get install libxslt-dev -y

安装Nginx,并指定某些依赖包的位置:

cd /tmp
# 官方下载列表:https://nginx.org/en/download.html
wget https://nginx.org/download/nginx-1.16.1.tar.gz
tar -xzvf nginx-1.16.1.tar.gz
cd nginx-1.16.1

# 开始编译安装
./configure \
--prefix=/usr/local/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--http-log-path=/usr/local/nginx/logs/access.log \
--error-log-path=/usr/local/nginx/logs/error.log \
--lock-path=/usr/local/nginx/nginx.lock \
--pid-path=/usr/local/run/nginx.pid \
--with-debug \
--with-pcre-jit \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_realip_module \
--with-http_auth_request_module \
--with-http_addition_module \
--with-http_dav_module \
--with-http_geoip_module \
--with-http_gunzip_module \
--with-http_v2_module \
--with-http_sub_module \
--with-http_xslt_module \
--with-stream \
--with-stream_ssl_module \
--with-mail \
--with-mail_ssl_module \
--with-threads \
--with-file-aio \
--with-pcre=/tmp/pcre-8.36 \
--with-openssl=/tmp/openssl-1.1.0g \
--with-zlib=/tmp/zlib-1.2.11 \
&& make && make install && echo OK.

# 为了用起来方便,可以改下权限,省去sudo:
sudo chown -R ubuntu:ubuntu /usr/local/nginx/

注意:

  • 上面configure里面没有指定rewriteopenssl等模块是因为,这些模块都是编译时候默认安装的,如果不想要可以用--without-http_rewrite_module来代替。
  • 指定模块安装路径时候结尾一定不要/,正确的是:-with-pcre=/tmp/pcre-8.36
  • 路径中不要用~,而是用展开的全路径,否则默写依赖模块不能识别
  • 如果安装中断报错:src/core/ngx_regex.h:15:18: fatal error: pcre.h: No such file or directory,那么说明PCRE版本问题。不要用PCRE版本2xx,直接选用pcre-8.36即可。
  • 记得在nginx.conf里面调用的文件,最好也指定自己有权限的文件,这样就不用任何sudo了

@solomonxie
Copy link
Owner Author

Nginx配合GeoIP实现block某些国家地区的访问

注意:这种地理限制,只会对HTTP/HTTPS生效。对于tcp流量转发一类,这个做不到。

# 安装数据库及相关的lib
sudo apt-get install geoip-database libgeoip1 libgeoip-dev

# 备份
sudo mv /usr/share/GeoIP/GeoIP.dat /usr/share/GeoIP/GeoIP.dat_bak

# 下载最新的库,只有4k左右 (如果此连接失效,则搜索 "github GeoIP.dat")
cd /usr/share/GeoIP/
sudo wget https://github.com/maxmind/geoip-api-c/raw/master/data/GeoIP.dat

# 此时目录有:
/usr/share/GeoIP$ ls
GeoIP.dat  GeoIP.dat_bak  GeoIPv6.dat

然后需要配置nginx的主配置文件:

http {
    # 其它配置...

    # 这个地方只是用来设置 $allowed_country 变量值
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    map $geoip_country_code $allowed_country {
        default no;
        CN yes;
        US no;
    }
    # IF语句必须放在http的server的location里面才行:
    server {
        location / {
            if ($allowed_country = no) {
                return 404;
            }
            # 也可以这么写,更简单直接,连上面的map字典也用不到:
            if ($geoip_country_code = CN) {
                return 404
            }
        }
    }

   # 其它配置...
}

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 21, 2020

iptables的乾坤大挪移

流量转发、端口转发——俗称NAT,翻译为乾坤大挪移

参考:https://github.com/shadowsocks/shadowsocks/wiki/Setup-a-Shadowsocks-relay

 sudo su
 echo 1 > /proc/sys/net/ipv4/ip_forward
 iptables -t nat -A PREROUTING -p tcp --dport 8388 -j DNAT --to-destination US_VPS_IP:8388
 iptables -t nat -A POSTROUTING -p tcp -d US_VPS_IP --dport 8388 -j SNAT --to-source JAPAN_VPS_IP

备份/恢复iptables设置

参考:https://upcloud.com/community/tutorials/configure-iptables-centos/

sudo su
iptables-save > /etc/iptables-rules
iptables-restore < /etc/iptables-rules

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 23, 2020

Mac 安装Shadowsocks算法依赖

libsodium依赖

默认Homebrew安装libsodium经常会在下载源码包的时候卡住下载不动,因为源码会从libsodium官网去下,官网速度非常慢。

参考:https://bin.zmide.com/?p=408

wget https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz
tar xzvf libsodium*.tar.gz
cd libsodium*
./configure
make -j8 && make install
pip install https://github.com/shadowsocks/shadowsocks/archive/master.zip --user

更好的方法是homebrew

# 在外网的环境下安装(需要代理)
# ...

$ brew install shadowsocks-libev

@solomonxie
Copy link
Owner Author

❖ 进入IRC的世界

Feb 8, 2019

IRC是人类古代时期的聊天工具,比QQ还早。但是IRC因为实现简单,让人与人之间聊天变得方便很多。我们可以在桌面上打开软件和对方聊,可以从网页里和对方聊,更可以在终端命令行里和对方聊。
IRC不用复杂的注册验证,简单到给自己起个昵称就能开聊。
只是IRC缘起就是给Geek用的,需要学会很多命令和流程。对程序员来说都是毛毛雨,对麻瓜来说,有些设计就有点反人类了。当然,是针对QQ、微信之类的聊天工具来说。

为什么要用IRC?
其实这个不是那么方便,要说什么小巧、容易之类都是自欺欺人。真正想玩IRC的人,都是有着对技术的强烈好奇心。就像放着IDE不用而非要用Vim,放着好好的邮件客户端不用而非用Mutt一样。就是一种探索精神,一种探索新“魔法”的精神。

GUI版和网页版的IRC客户端就不多说了。这里说说命令行里的客户端。
实际上,很多IRC的GUI客户端都很丑,还不如直接在命令行里安装使用来的方便。

目前最流行都CLI版本IRC客户端是这两个:

  • Irssi, 轻量级流行客户端
  • WeeChat, 重量级客户端,配置文件超多,运行速度卡顿。

这里我们讲Irssi

Irssi: 命令行版的IRC Client客户端

安装:

# Mac
brew install irssi

# Ubuntu
apt install irssi

命令行输入irssi即进入了聊天室。

image

和一般Linux程序的一般命令、格式都不同,IRC客户端一般有自己的命令。

下方[(status)]是输入命令的地方。

一般命令(不区分大小写):

  • /quit,退出程序。一般的ctrl-c, ctrl-d, esc, q之类的都不管用
  • /help,帮助
  • /network list 查看已保存的服务器列表
  • /connect xxx.xxx.xxx 连接某服务器
  • /join xxx 加入某channel
  • /leave/part 离开当前channel
  • /normal/n 查看当前channel的人数
  • /list -YES 查看当前服务器的所有chennels (慎用)
  • /nick NewNickName 更改当前昵称
  • /msg NickName Content 给某人发送消息,一般都是给/msg nickserv管理人NPC发送消息

尝试一下完整流程:

/connect irc.dal.net
/join #lobby

[#lobby] hello there!

/part

常用快捷键:

  • Alt + 1/2/3/4...,切换window窗口,一般一个channel一个窗口
  • Alt + n/p,上下滚动屏幕

配置IRSSI

如果想长期保存、备份一个固定的程序配置,那么就需要修改配置文件。
irssi默认的配置文件为~/.irssi/config

配置中,会在第一次运行时就自动设置了一些,包括根据当前电脑账户的用户名设置nickname等。
整个配置,是一直“类似”JSON的格式。

配置中包含的常用内容:

  • settings 记录自己的名字:nick, real_name, user_name
  • servers 不要误会,这是指的Network而不是具体某台server,如freenode, dal, esper等大型网络
  • chatnets 记录各个网络的登录信息,也可以作为“别名”,这样每次/connect不用输入全路径了
  • channels 记录自己收藏的频道名

界面美化的设置:

  • statusbar

常用服务器列表

首先要区分一些概念:

  • Networks:是指的互相隔离的网络,如Freenode和DALnet这些是世界知名的网络,但互相隔离,频道不共享
  • Servers:Network网络中的某一台电脑服务器,你加入世界上任何一个server都能加入这个Network

全球常用的服务器,就那么几个:

  • Freenode
  • Dal
  • ESPer
  • EFnet

配置案例:

servers = (
  { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; },
  {
      address = "路径";
      chatnet = "下面chatnet对应的名称";
      port = "端口";
      autoconnect = true;
      use_ssl = "yes";
      password = "用户名:密码";
  }
);

配置完每个服务器后,相应的还要配置chatnets,每一条的名称都要与servers中的对应。
配置案例:

chatnets = {
    DALnet = {
        type = "IRC";
        max_kicks = "4"; max_msgs = "20";max_whois = "30";
    };
    Freenode = {
        type = "IRC";
        max_kicks = "4"; max_msgs = "20";max_whois = "30";
        autosendcmd = "/msg nickserv identify MyName MyPassword";
    };
};

常用频道列表

IRC的频道不是用URL之类很复杂的东西,全都是用#tag这种简单一个标签来区分的,非常好记。

配置案例:

channels = (
  { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; },
  { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; },
);

注册流程

一般大一点的服务器,都是必须要注册的,流程比较麻烦。以往传说里的各种匿名聊天,再也没有了。不注册,就不让你connect服务器。

每个大服务器的流程都不一样,一般是要跟服务器管家机器人nickserv对话,遵从指示才能正确完成注册。
不过大概流程相似:

  • 先确认自己当前的昵称:/nick
  • 连接服务器: /connect Freenode
  • 连接上后,再发送消息给机器人管家,如/msg nickserv register 我的密码 我的邮箱
  • 然后机器人会发送注册流程到你的邮箱
  • 查收邮件后按指示,在程序里切换到跟nickserv私聊的页面
  • 复制邮件里的验证命令,给它发过去,如/msg NickServ VERIFY REGISTER 我的名字 验证码

验证成功后,就会出现NickServ(NickServ@services.)- Thank you for verifying your e-mail address! You have taken steps in ensuring that your registrations are not exploited.

下次再登录,只需要每次在connect服务器后输入这个命令即可登录:

/msg nickserv identify MyName MyPassword

但是每次登录都这样输命令太麻烦。在配置文件里面我们可以在chatnet中配置登录后自动执行这个命令:

chatnet={
    Freenode = {
        #.....
        autosendcmd = "/msg nickserv identify MyName MyPassword";
    };
}

如果用的是手机客户端或GUI客户端的话,一般设置里面都有自动登录的用户名密码选项,效果是一样的。

TMUX颜色问题

如果在Tmux里运行,那么有可能会显示这个错误:

Irssi: warning You seem to be running Irssi inside tmux, but the TERM environment variable is set to 'xterm-256color', which can cause display glitches.
Irssi: Consider changing TERM to 'tmux' or 'tmux-256color' instead.

根据提示在~/.zshrc~/.bash_profile里面(而不是tmuxrc里),添加这个:

export TERM="tmux-256color"

发现zsh找不到这个color,而且无法启动程序。

色彩主题

目前IRSSI的世界里,唯一知名的主题只有weed

按照方法很简单,clone整个项目,把内容全部复制到~/.irssi/目录下。
注意:记得备份自己的~/.irssi/config文件,因为会被覆盖!

但是这个主题需要自己进入客户端后,手动输入命令加载script脚本才能生效: /script load awl

当然,官方有更方便的方法,进入客户端后自动加载指定的脚本,只要在~/.irssi/scripts/目录下创建一个autorun目录,然后把脚本复制到里面即可。

mkdir ~/.irssi/scripts/autorun/
cp ~/.irssi/scripts/awl.pl ~/.irssi/scripts/autorun/

然后再次打开irssi就会看到更现代化的主题了。

image

@solomonxie
Copy link
Owner Author

solomonxie commented Jul 23, 2020

多台路由器组成WDS无线桥接 [DRAFT]

背景:家里有一台主路由器放在大厅用来连接外网。另外多出来几台老路由器,还有几台老台式机,上面配有Linux系统作为服务器,想做到把台式机放在别的房间,再用老路由器通过网线连接把服务器连接到主网络里。然后要求能够在同一网段,可以ssh或远程桌面访问。

路由器组网有几种模式:

  • AP (Access Point) 接入点
  • Wireless Extension 无线中继
  • Wireless Bridge 无线桥接

无线中继设置很方便,几乎所有路由器都能支持。但是这只能做到副路由器能够正常访问外网,没法做到局域网内互通,因为网段不一样。
无线桥接,有时候也称为WDS,可以保证既能连接外围,又让副路由器在同一网段,但是只有副路由器具有WDS功能才行。

下面介绍几种家里的副路由器设置方法。

开始之前需要说明的是,

不需要主路由器做任何设置!全部设置都在副路由器。

极路由器1代 作为副路由

花了最长的时间研究、尝试,结果没成功。

TP-Link WR847N v2 作为副路由

花了很长时间不断尝试、重启,结果没成功。

参考标准的官方WDS文档,说的非常简单明了:
TL-WR847N V1 ~V3 无线桥接(WDS)如何设置

华为HG255D作为副路由

这个著名的华为HG255D,是从淘宝买的二手,花了30块钱。知名是因为它是这个价位可以装OpenWRT的很好选择。

Mercury MW305R 水星作为副路由

为了组WDS网,特意在淘宝上买了一个崭新的Mercury路由,49块钱,没想到设置WDS如此轻松,没看教程,全程只用了十几分钟。

  • 首先恢复出厂值
  • 随便找个Windows笔记本或台式机,把网线插在路由器Lan口上,不要查不一样颜色的WAN口
  • 输入192.168.1.1进入路由器主页
  • 跳过设置向导,进入高级设置
  • 进入无线设置 -> WDS无线桥接 -> 开启
    image
  • 选择主路由,输入密码,连接
  • 打开 网络参数 -> DHCP服务器 -> 关闭 一般来讲WDS组网都是要关闭副路由的DHCP自动分配IP地址的,因为这个工作要交给主路由来分配
    image
  • 打开 网络参数 -> LAN口设置 -> 手动 ,这里是要设置副路由器在主网络里的IP地址,这里最重要!一定要把它设置在主路由的网段里,如果主路由是 192.168.1.1, 那这里可以设置 192.168.1.2等等,只要不和别的设备冲突就行。
    image
  • 保存后理论上就已经完成了。
  • 这时候还可以到 无限设置 -> 主人网络 来确定下所连接主路由的WiFi是否正确。
  • 打开任意网站,看看是不是可以联网
  • 打开cmd命令行,输入 ipconfig 查看自己是否和主路由在同一网段
  • ping 主路由和局域网内其它设备的地址

@solomonxie
Copy link
Owner Author

Ubuntu 部署Samba文件共享服务器

Refer to: https://ubuntu.com/tutorials/install-and-configure-samba#1-overview

sudo apt install samba -y
mkdir ~/sambashare/
sudo echo [sambashare] >> /etc/samba/smb.conf
sudo echo     comment = Samba on Ubuntu >> /etc/samba/smb.conf
sudo echo     path = /home/solnas/sambashare >> /etc/samba/smb.conf
sudo echo     read only = no >> /etc/samba/smb.conf
sudo echo     browsable = yes >> /etc/samba/smb.conf
sudo service smbd restart
sudo smbpasswd -a solnas

@solomonxie
Copy link
Owner Author

solomonxie commented Feb 28, 2021

OpenWrt 配置HTTP Proxy透明代理

一般我们自己路由器的话,喜欢安装OpenWrt系统,而且会配置Shadowsocks/V2Ray等服务端,然后在局域网内共享它们的服务端口,比如1080之类的。
但是这些服务端口共享出来的,一般都是Socks协议,也就是说我们必须在电脑/手机/浏览器上安装支持socks的专门程序才行。但是对于没有安装这些客户端程序的客户端来说,非常的不友好。比如家人的iPhone手机,绝大部分都不会有美区apple账号去下载shadowrocket客户端。比如家中的电视盒子,也很难安装支持socks的客户端让你看netflix。

这种情况下,最好的解决方法就是要把socks的服务端口转换成http端口,这样任何设备都可以在连wifi的时候设置http proxy代理,也就是透明代理。

把Socks代理转发成Http代理,需要privoxy程序,用ssh登入路由器后:

# Openwrt安装privoxy
opkg install privoxy

# 编辑配置文件
vim /etc/config/privoxy

下面是配置文件,注意,我们监听路由器上socks端口1080,然后把它转发为1088,而不是默认的8118。因为如果使用默认的比较不安全容易被人利用,很可能在防火墙内已经被屏蔽。所以我们换另外一个端口:

# /etc/config/privoxy >>>
listen-address 0.0.0.0:1088
toggle  1
enable-remote-toggle 1
enable-remote-http-toggle 1
enable-edit-actions 0
enforce-blocks 0
buffer-limit 4096
forwarded-connect-retries  0
accept-intercepted-requests 0
allow-cgi-request-crunching 0
split-large-forms 0
keep-alive-timeout 5
socket-timeout 60

forward-socks5 / 127.0.0.1:1080 .
forward         192.168.*.*/     .
forward         10.*.*.*/        .
forward         127.*.*.*/       .
# <<< END OF FILE

这时候我们手动启用程序,并在后台运行:

nohup privoxy /etc/privoxy/config > /tmp/privoxy.log &

然后在路由器本机实验转发是否成功:

all_proxy=http://127.0.0.1:1088 curl https://httpbin.org/ip

如果上面返回的是期待的服务器IP,就证明配置成功了。

然后回到自己的电脑上,试试看连接路由器这个http-proxy端口是否能成功:

all_proxy=http://192.168.1.xxx:1088 curl https://httpbin.org/ip

如果成功就万事大吉。但是也有可能因为防火墙没有开放这个端口,导致访问失败。
这时候需要到firewall里开放这个端口的访问权限。iptables命令行配置比较麻烦,可以直接到openwrt的页面上点击菜单 -> 网络 -> 防火墙 -> 流量规则 -> ”打开路由器端口“栏目 -> 输入端口号和协议 -> 添加 -> 保存配置:
image

这时候在路由器的命令行里输入 iptables -L 然后搜索1088,看看是否配成功,主要看是否有其它程序也占用了这个端口。如果没有,我们就再回到自己主机上尝试:

all_proxy=http://192.168.1.xxx:1088 curl https://httpbin.org/ip

基本上到这里就没太大问题了。

至于手机、电视盒子等客户端,都可以在wifi连接的设置里找到手动设置代理的地方,填入局域网的路由器IP和刚刚配置的端口,就可以连接上了。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant