关注小众语言,记录、分享技术点滴!

0%

在lua原生语法特性中是不具备面向对象设计的特性。因此,要想在lua上像其他高级语言一样使用面向对象的设计方法,就需要使用原生的元表(metatable)来模拟面向对象设计。

一、元表setmetatable
对指定 table 设置元表(metatable),如果元表(metatable)中存在__metatable键值,setmetatable会失败。

以下实例演示了如何对指定的表设置元表:

1
2
3
mytable = {}                          -- 普通表
mymetatable = {} -- 元表
setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表

二、元表__index 元方法
这是 metatable 最常用的键。
当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的_index 键。如果_index包含一个表格,Lua会在表格中查找相应的键。

1
2
3
4
5
6
other = { foo = 3 }
t = setmetatable({}, { __index = other })
print(t.foo)
3
print(t.bar)
nil

三、使用metatable实现继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local _M = {
version = 'lua 1.0'
}

local parent = {
__index = _M
}

function parent.new()
-- 初始化new,如果没有这句,那么类所建立的对象如果有一个改变,其他对象都会改变
local new = {}
-- 使用setmetatable来实现继承
setmetatable(new, parent)
return new
end

function _M:echo()
print("M:echo "..self.version)
end

四、使用metatable实现重载和多态

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
local _M = {
version = 'lua 1.0'
}

local parent = {
__index = _M
}

function parent.new()
-- 初始化new,如果没有这句,那么类所建立的对象如果有一个改变,其他对象都会改变
local new = {}
-- 使用setmetatable来实现继承
setmetatable(new, parent)
return new
end

function _M:echo()
print("M:echo "..self.version)
end


local _M2 = parent.new()

local child = {
__index = _M2
}

function child.new()
-- 初始化new,如果没有这句,那么类所建立的对象如果有一个改变,其他对象都会改变
local new = {}
-- 使用setmetatable来实现继承
setmetatable(new, child)
return new
end

-- 重载echo方法
function _M2:echo()
print("M2:echo "..self.version)
end


test = parent.new()
test:echo()

test = child.new()
test:echo()

luaosslluacrypto的代替版本,是针对 Lua 5.1、5.2、5.3 和 LuaJIT 的 OpenSSL 综合绑定。是 Lua 世界中最全面的 OpenSSL 绑定。luaosll安装依赖OpenSSL库,所以需要先安装OpenSSL。

一、安装OpenSSL
下载好的OpenSSL源码目录下,编译安装OpenSSL(以下均使用默认路径“/usr/local”进行安装)

1)生成Makefile文件

1
2
# 根据编译平台及环境自动生成Makefile文件,可以通过./config --prefix指定安装路径,-Wl,-rpath参数指定OpenSSL运行时依赖libcrypto、libssl库的路径。
./config -Wl,-rpath,/usr/local/lib

2)安装OpenSSL

1
2
make
make install

3)查看OpenSSL版本

1
2
3
4
openssl version

# 显示如下格式内容说明安装成功(本文以安装OpenSSL 1.1.1q为例)
OpenSSL 1.1.1q 5 Jul 2022 (Library: OpenSSL 1.1.1k FIPS 25 Mar 2021)

二、安装luaosll

1
2
3
4
5
6
7
8
9
10
11
12
luarocks install luaossl

# 显示如下格式内容说明安装成功
Installing https://luarocks.org/luaossl-20220711-0.src.rock

luaossl 20220711-0 depends on lua (5.1-1 provided by VM)
Applying patch config.h.diff...
Hunk 1 found at offset 2...
gcc -O2 -fPIC -I/usr/local/include -c src/openssl.c -o src/openssl.o -D_REENTRANT -D_THREAD_SAFE -DCOMPAT53_PREFIX=luaossl -D_GNU_SOURCE -I/usr/local/include -I/usr/local/include
gcc -O2 -fPIC -I/usr/local/include -c vendor/compat53/c-api/compat-5.3.c -o vendor/compat53/c-api/compat-5.3.o -D_REENTRANT -D_THREAD_SAFE -DCOMPAT53_PREFIX=luaossl -D_GNU_SOURCE -I/usr/local/include -I/usr/local/include
gcc -shared -o _openssl.so src/openssl.o vendor/compat53/c-api/compat-5.3.o -L/usr/local/lib64 -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto -lpthread -lm -ldl
luaossl 20220711-0 is now installed in /usr/local (license: MIT/X11)

KEDA 是一个基于 Kubernetes 的事件驱动自动缩放器。使用 KEDA,您可以根据需要处理的事件数量来驱动 Kubernetes 中任何容器的扩展。KEDA可以支持很多自定义事件源,如:Mysql、MongoDB、Redis、ActiveMQ、Kafka、Prometheus、Metrics API等。本文使用nginx中的stub_status数据 + Prometheus为事件源进行KEDA HPA配置。

一、开启nginx(stub_status)
nginx中的stub_status模块主要用于查看Nginx的一些状态信息。

1)查看nginx时候有安装该模块。

1
/usr/local/nginx/sbin/nginx -V

2)安装stub_status模块
(注意:有的话可以忽略此步骤,就不用安装了)
在nginx编译安装的时候加上参数 “–with-http_stub_status_module”,就安装了这个模块。

1
./configure --with-http_stub_status_module

3)开启stub_status

1
2
3
4
5
location /nginx_status {
stub_status on;
allow 127.0.0.1; #only allow requests from localhost
deny all; #deny all other hosts
}

二、在kubernetes中运行nginx-prometheus-exporter
nginx-prometheus-exporter 是将 stub_status 指标转换为 Prometheus 指标类型,最终可以由 Prometheus 进行收集。

在Kubernetes里运行

1)创建一个无状态服务(Deployment)

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
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-prometheus
labels:
workload.user.cattle.io/workloadselector: apps.deployment-default-nginx-prometheus
namespace: default
spec:
selector:
matchLabels:
workload.user.cattle.io/workloadselector: apps.deployment-default-nginx-prometheus
template:
metadata:
labels:
workload.user.cattle.io/workloadselector: apps.deployment-default-nginx-prometheus
spec:
containers:
- imagePullPolicy: Always
name: nginx-prometheus
image: nginx/nginx-prometheus-exporter:0.10.0
command:
- nginx-prometheus-exporter
args:
- '-nginx.scrape-uri=http://127.0.0.1/nginx_status'
restartPolicy: Always

2)创建一个Service服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
name: nginx-prometheus
labels:
metrics-prometheus-discovery: 'true' # for monitoring discovery
namespace: default
spec:
ports:
- name: prometheus
port: 9113
protocol: TCP
targetPort: 9113
type: ClusterIP

三、配置kubernetes中的Monitor服务

1)创建一个ServiceMonitor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: nginx-monitor
namespace: default
spec:
selector:
matchLabels:
metrics-prometheus-discovery: 'true' # for monitoring discovery
namespaceSelector:
matchNames:
- default
endpoints:
- port: prometheus
interval: 5s

2)创建KEDA(ScaledObject)缩放规则

Prometheus的集群内访问地址是:http://prometheus-operated.cattle-prometheus.svc:9090

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: nginx-prometheus-scaledobject
namespace: default
spec:
scaleTargetRef:
name: nginx
pollingInterval: 5 # Optional. Default: 30 seconds
cooldownPeriod: 60 # Optional. Default: 300 seconds
minReplicaCount: 1 # Optional. Default: 0
maxReplicaCount: 3 # Optional. Default: 100
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus-operated.cattle-monitoring-system.svc.cluster.local:9090
metricName: nginx_http_requests_total
threshold: '100'
query: sum(rate(nginx_http_requests_total[10s]))

ps:

在Docker中运行

1
docker run -p 9113:9113 nginx/nginx-prometheus-exporter:0.10.0 -nginx.scrape-uri=http://127.0.0.1/nginx_status

运行后,可以通过9113 端口来访问 Prometheus 收集的数据,可以配合Grafana来实现数据可视化。

1
curl http://localhost:9113/metrics

在开发环境及私有环境下需要使用SSL,于是使用openssl创建自签发证书,支持多域名、泛域名、直接IP访问。

一、使用openssl生成证书自签名

openssl在centos中是标配,所以直接在centos中操作,因为要多个域名和IP,故而需要编辑一个配置文件,如下:

1
$ vim req.cnf
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
# 定义输入用户信息选项的"特征名称"字段名,该扩展字段定义了多项用户信息。
distinguished_name = req_distinguished_name
# 生成自签名证书时要使用的证书扩展项字段名,该扩展字段定义了要加入到证书中的一系列扩展项。
x509_extensions = v3_req

# 如果设为no,那么 req 指令将直接从配置文件中读取证书字段的信息,而不提示用户输入。
prompt = no

[req_distinguished_name]
#国家代码,一般都是CN(大写)
C = CN
#省份
ST = Beijing
#城市
L = Beijing
#企业/单位名称
O = phpkoo
#企业部门
OU = phpkoo
#证书的主域名
CN = phpkoo.com

##### 要加入到证书请求中的一系列扩展项 #####
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1=第一个域名
DNS.2=第二个域名
DNS.N=第N个域名
IP.1=第一个IP
IP.2=第二个IP
IP.N=第N个IP

其中IP配置项,可有可无。

1
2
$ mkdir -p ssl/
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ssl/private.key -out ./ssl/ssl.crt -config ./req.cnf -sha256

至此证书生成完成

可以下载ssl目录下的private.key和ssl.crt文件

openssl 命令参数说明:

req 大致有3个功能:生成证书请求文件、验证证书请求文件和创建根CA。
-x509 说明生成自签名证书。
-nodes openssl req在自动创建私钥时,将总是加密该私钥文件,并提示输入加密的密码。可以使用”-nodes”选项禁止加密私钥文件。
-days 指定所颁发的证书有效期。
-key 指定输入的密钥,如果不指定此选项会根据 -newkey 选项的参数生成密钥对。
-newkey 指定生成一个新的密钥对,只有在没有 -key 选项的时候才生效,参数形式为rsa:numbits或者dsa:file,例如:rsa:2048 rsa表示创建rsa私钥,2048表示私钥的长度。
-keyout 指定私钥保存位置。
-out 新的证书请求文件位置。
-config 指定req的配置文件,指定后将忽略所有的其他配置文件。如果不指定则默认使用/etc/pki/tls/openssl.cnf中req段落的值。

二、证书如何使用

此时访问会出现如下问题

你还得在系统上安装一下证书,安装步骤如下
1、在Windows中导入证书

  • 第一步:双击ssl.crt文件打开证书文件,出现如下界面

  • 第二步:

  • 第三步:

  • 第四步:

  • 第五步:

证书安装,完成

重启浏览器,才能生效

2、测试效果

3、火狐浏览器处理

Firefox默认情况不,还是不信任自签名证书

打开火狐浏览器输入about:config进行设置界面

  • 第一步:

  • 第二步:

输入security.enterprise_roots.enabled修改为true

  • 第三步:

设置完成

重启浏览器,才能生效

在一次和国内某云厂商对接对象存储时,因为他们对象存储服务,是直接使用的是第三方开源服务,开源服务默认并不支持chunked编码(而国内其它大厂一般都是支持chunked编码)。导致上传文件一直报HTTP/1.1 411 Length Required错误,出现问题的原因是说,我没有传Content-Length。

而明明我在header里设置了Content-Length,但是抓包发现,实际却变成了chunked

经过反复的测试情况都依旧,直到在github上找到了这个https://github.com/golang/go/issues/16264

然后查看了golang源码

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
func NewRequest(method, url string, body io.Reader) (*Request, error) {
if method == "" {
// We document that "" means "GET" for Request.Method, and people have
// relied on that from NewRequest, so keep that working.
// We still enforce validMethod for non-empty methods.
method = "GET"
}
if !validMethod(method) {
return nil, fmt.Errorf("net/http: invalid method %q", method)
}
u, err := parseURL(url) // Just url.Parse (url is shadowed for godoc).
if err != nil {
return nil, err
}
rc, ok := body.(io.ReadCloser)
if !ok && body != nil {
rc = ioutil.NopCloser(body)
}
// The host's colon:port should be normalized. See Issue 14836.
u.Host = removeEmptyPort(u.Host)
req := &Request{
Method: method,
URL: u,
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
Header: make(Header),
Body: rc,
Host: u.Host,
}
if body != nil {
switch v := body.(type) {
case *bytes.Buffer:
req.ContentLength = int64(v.Len())
buf := v.Bytes()
req.GetBody = func() (io.ReadCloser, error) {
r := bytes.NewReader(buf)
return ioutil.NopCloser(r), nil
}
case *bytes.Reader:
req.ContentLength = int64(v.Len())
snapshot := *v
req.GetBody = func() (io.ReadCloser, error) {
r := snapshot
return ioutil.NopCloser(&r), nil
}
case *strings.Reader:
req.ContentLength = int64(v.Len())
snapshot := *v
req.GetBody = func() (io.ReadCloser, error) {
r := snapshot
return ioutil.NopCloser(&r), nil
}
default:
// This is where we'd set it to -1 (at least
// if body != NoBody) to mean unknown, but
// that broke people during the Go 1.8 testing
// period. People depend on it being 0 I
// guess. Maybe retry later. See Issue 18117.
}
// For client requests, Request.ContentLength of 0
// means either actually 0, or unknown. The only way
// to explicitly say that the ContentLength is zero is
// to set the Body to nil. But turns out too much code
// depends on NewRequest returning a non-nil Body,
// so we use a well-known ReadCloser variable instead
// and have the http package also treat that sentinel
// variable to mean explicitly zero.
if req.GetBody != nil && req.ContentLength == 0 {
req.Body = NoBody
req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
}
}

return req, nil
}

可以看到,这里面居然有个switch,当你使用bytes.Buffer,bytes.Reader或者strings.Reader作为Body的时候,它会自动给你设置req.ContentLength…

所以,问题不是当你Post一个ReadCloser的时候,就会变成chunked,而是你Post非这三种类型的body进来的时候都没有Content-Length,需要自己显式设置。代码如下:

1
2
req, _ := http.NewRequest(method, url, bodyReader)
req.ContentLength = req.Header.Get("Content-Length")

设置了req.ContentLength之后,抓包如下确实不再是chunked编码了,抓包如下

至此问题解决。

lua-mongo 是对 MongoDB C Driver 1.16 或更高版本的 Lua 的绑定,githup仓库:https://github.com/neoxic/lua-mongo

通过luarocks方式安装lua模块

一、安装luarocks工具,官网:https://luarocks.org/
二、安装lua-mongo模块

1
luarocks install lua-mongo

安装时,报以下错误信息

Error: Could not find expected file libmongoc-1.0/mongoc.h, or libmongoc-1.0/mongoc.h for LIBMONGOC – you may have to install LIBMONGOC in your system and/or pass LIBMONGOC_DIR or LIBMONGOC_INCDIR to the luarocks command. Example: luarocks install mongorover LIBMONGOC_DIR=/usr/local

三、安装cmake

因为mongo-c-driver需要使用cmake进行编译

1
2
3
4
5
6
7
yum install gcc gcc-c++ ncurses-devel
wget wget https://cmake.org/files/v3.3/cmake-3.3.2.tar.gz
tar -xzf cmake-3.3.2.tar.gz
cd cmake-3.3.2/
./bootstrap
gmake
gmake install

四、安装libmongoc库

官方安装参照:http://mongoc.org/

1
2
3
4
5
6
wget https://github.com/mongodb/mongo-c-driver/releases/download/1.17.6/mongo-c-driver-1.17.6.tar.gz
tar -xzf mongo-c-driver-1.17.6.tar.gz
cd mongo-c-driver-1.17.6/
cmake .
make
make install

再执行,安装lua-mongo模块

1
luarocks install lua-mongo

安装成功

nginx想支持openresty的功能,需要安装以下模块及依赖luajit2lua-resty-corelua-resty-lrucachelua-nginx-modulengx_devel_kit以下5个依赖包必须先下载,另外如果需要同时支持SSL的话,还需要下载openssl依赖包(ssl只需要下载nginx编译时使用)。

一、安装openresty依赖包
1、安装luajit2(下载最新版本)

1
2
3
4
5
6
7
8
9
wget https://github.com/openresty/luajit2/archive/v2.1-20201229.tar.gz
tar -zxvf luajit2-2.1-20201229.tar.gz
cd luajit2-2.1-20201229
make
make install

#导入环境变量(编译nginx时需要)
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.1

2、安装lua-resty-core

1
2
3
4
wget https://github.com/openresty/lua-resty-core/archive/v0.1.21.tar.gz
tar -zxvf lua-resty-core-0.1.21.tar.gz
cd lua-resty-core-0.1.21
make install

3、安装lua-resty-lrucache

1
2
3
4
wget https://github.com/openresty/lua-resty-lrucache/archive/v0.10.tar.gz
tar -zxvf lua-resty-lrucache-0.10.tar.gz
cd lua-resty-lrucache-0.10
make install

4、解压lua-nginx-module

1
2
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.19.tar.gz
tar -zxvf lua-nginx-module-0.10.19.tar.gz

5、解压ngx_devel_kit

1
2
wget https://github.com/vision5/ngx_devel_kit/archive/v0.3.1.tar.gz
tar -zxvf ngx_devel_kit-0.3.1.tar.gz

6、解压openssl

1
2
wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
tar -zxvf openssl-1.1.1k.tar.gz

二、编译及安装nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar -zxvf nginx-1.18.0.tar.gz

./configure --prefix=/usr/local/nginx \
--with-openssl=/usr/local/src/openssl-1.1.1k \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_gzip_static_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-http_slice_module \
--with-compat \
--with-file-aio \
--with-http_v2_module \
--with-ld-opt="-Wl,-rpath,/usr/local/lib" \
--add-module=/usr/local/src/ngx_devel_kit-0.3.1 \
--add-module=/usr/local/src/lua-nginx-module-0.10.19

make && make install

三、nginx配置

1
2
3
4
5
6
#设置openresty模块目录
lua_package_path "/usr/local/lib/lua/?.lua;/usr/local/nginx/conf/lua/?.lua;;";

#指定dns解析服务器,实现动态upstream
resolver 114.114.114.114 223.5.5.5 1.1.1.1 8.8.8.8 valid=30;
resolver_timeout 5;

四、hello openresty(/usr/local/nginx/conf/lua/hello.lua)

1
ngx.print("hello openresty!")

一、lsof相关使用
1、系统所有进程打开对应的句柄数

1
lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more

2、查看当前进程实时打开的文件数

1
lsof -p 进程ID |wc -l

3、查看被打开某一文件的相关进程信息

1
lsof /proc

4、查看监听端口25的进程

1
lsof -i:25

5、查看活动的连接

1
lsof -i @192.168.1.2

二、查看当前进程持有文件句柄数量和文件句柄最大限制

1、查看这个PID持有的句柄数

1
ls /proc/进程ID/fd | wc -l

2、查看当前进程句柄数量限制

1
cat /proc/进程ID/limits | grep "files"

三、查看系统总限制

1、查看系统总限制打开文件的最大数量

1
cat /proc/sys/fs/file-max

四、watch命令
watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行。在Linux下,watch是周期性的执行下个程序,并全屏显示执行结果。

1、每隔一秒高亮显示网络链接数的变化情况

1
watch -n 1 -d netstat -ant

2、每隔一秒高亮显示http链接数的变化情况

1
watch -n 1 -d 'pstree|grep http'

3、实时查看模拟攻击客户机建立起来的连接数

1
watch 'netstat -an | grep:21 | \ grep<模拟攻击客户机的IP>| wc -l'

4、10秒一次输出系统的平均负载

1
watch -n 10 'cat /proc/loadavg'

5、监测磁盘inode和block数目变化情况

1
watch -n 1 'df -i;df'

Composer 是 PHP 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。

运行 Composer 需要 PHP 5.3.2+ 以上版本。一些敏感的 PHP 设置和编译标志也是必须的,但对于任何不兼容项安装程序都会抛出警告。

全局安装 (推荐)

1
2
3
curl -sS https://getcomposer.org/installer | php

mv composer.phar /usr/local/bin/composer

局部安装

1
curl -sS https://getcomposer.org/installer | php

全局配置(推荐)

阿里 Composer 全量镜像

1
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

取消配置

1
composer config -g --unset repos.packagist

Xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作。
  Xftp是一种灵活且轻量级的SFTP/FTP客户端,用于需要安全地通过网络传输文件的用户。文件传输被简化,使用拖拽、直接编辑和增强的同步,这些特性在直观的标签界面中被封装。

Xshell & Xftp 显示评估期已过,怎么解决?

一、 卸载所有版本的Xshell,Xmanager,Xftp,Xldp和Netsarang产品,并从注册表中删除 NetSarang 目录 (HKEY_CURRENT_USER\Software\NetSarang)。

二、下载 Xshell 6 & Xftp 6

下载方式

http://www.netsarang.com/download/main.html 选择下载评估版,收到下载地址后将下载地址加上r。
例如 https://cdn.netsarang.net/f8a8d224/XmanagerPowerSuite-6.0.0009.exe
改为 https://cdn.netsarang.net/f8a8d224/XmanagerPowerSuite-6.0.0009r.exe
如果下载不带r的版本,无法输入序列号,注意不要下载到“思杰马克丁”特供版,下载完毕后,对安装包右键,属性,数字签名,如果是官方版则是“NetSarang Computer, Inc.”。

三、 添加路由到 C:\Windows\System32\drivers\etc\hosts

127.0.0.1 transact.netsarang.com
127.0.0.1 update.netsarang.com
127.0.0.1 www.netsarang.com
127.0.0.1 www.netsarang.co.kr
127.0.0.1 sales.netsarang.com

四、一定要在前三步骤做完之后再安装带r版本的 Xshell6 & Xftp6

注册码
Xshell Plus 6 : 180505-117501-020791
Xmanager Power Suite 6 :180429-116253-999126

五、安装完成后,将对应的程序运行一次后,打开注册表,将下列字段设置为当前用户拒绝全部权限,否则会反弹

HKEY_CURRENT_USER\Software\NetSarang\Xftp\6\LiveUpdate
HKEY_CURRENT_USER\Software\NetSarang\Xlpd\6\LiveUpdate
HKEY_CURRENT_USER\Software\NetSarang\Xmanager\6\LiveUpdate
HKEY_CURRENT_USER\Software\NetSarang\Xshell\6\LiveUpdate

打开注册表程序(开始 -> 运行 -> regedit 或 win + R 打开运行输入 regedit 回车进入注册表编辑器)

点击 “高级”

禁用继承

权限转换

编辑并取消各用户的所有权限

已注册的Xshell6

Xftp同样按照以上步骤操作,把权限去掉即可。

六、彻底禁用 Xshell & Xftp 更新

xshell菜单—-工具—选项
在选项设置里面,点击更新选项卡,去掉实时更新的勾选

删除更新程序

也可以把 LiveUpdate.exe 换成别的一个空文件来替换

注册码可以用这个生成
https://github.com/DoubleLabyrinth/Xmanager-keygen
需要用Python3.6 执行