fanqiang 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,6 +33,8 @@ Options:
33
33
  [string] [default: "us-east-1"]
34
34
  --tunnel-region Aliyun region for tunnel deployment
35
35
  [string] [default: "cn-shanghai"]
36
+ --bucket AWS S3 bucket name, used to store clash client configuration file
37
+ [string] [default: "fanqiang-$USER"]
36
38
  --help Show help [boolean]
37
39
  --version Show version number [boolean]
38
40
  ```
@@ -43,7 +45,7 @@ You need to configure an AWS IAM user on the local machine before running any co
43
45
  supports reading AWS credentials from <code>Shared Credentials File</code>:
44
46
 
45
47
  - The shared credentials file on Linux, Unix, and macOS: ~/.aws/credentials
46
- - The shared credentials file on Windows: C:\Users\USER_NAME\.aws\credentials
48
+ - The shared credentials file on Windows: C:\Users\USER_NAME\\.aws\credentials
47
49
 
48
50
  An example of credentials file:
49
51
 
@@ -63,7 +65,7 @@ You need to configure an Aliyun RAM user on a local machine if you want to use -
63
65
  supports reading credentials from <code>$HOME/.alibabacloud/credentials</code>:
64
66
 
65
67
  - The credentials file on Linux, Unix, and macOS: ~/.alibabacloud/credentials
66
- - The credentials file on Windows: C:\Users\USER_NAME\.alibabacloud\credentials
68
+ - The credentials file on Windows: C:\Users\USER_NAME\\.alibabacloud\credentials
67
69
 
68
70
  An example of credentials file:
69
71
 
@@ -1 +1 @@
1
- {"version":3,"file":"TerraformTunnelProxyOperations.d.ts","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,qBAAa,8BAA+B,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEnD,MAAM,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAY/E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B"}
1
+ {"version":3,"file":"TerraformTunnelProxyOperations.d.ts","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMhD,qBAAa,8BAA+B,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEnD,MAAM,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAoB/E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B"}
@@ -5,12 +5,23 @@ const tslib_1 = require("tslib");
5
5
  const terraform = tslib_1.__importStar(require("./terraform"));
6
6
  const AwsS3CloudStorage_1 = require("./AwsS3CloudStorage");
7
7
  const fs = tslib_1.__importStar(require("fs-extra"));
8
+ const net = tslib_1.__importStar(require("net"));
9
+ const promise_retry_1 = tslib_1.__importDefault(require("promise-retry"));
8
10
  class TerraformTunnelProxyOperations {
9
11
  constructor(configuration) {
10
12
  this.configuration = configuration;
11
13
  }
12
14
  async create(request) {
13
15
  const applyResult = await terraform.apply(request, this.configuration.terraformWorkspace, this.configuration.aliyun.credentials);
16
+ await promise_retry_1.default(async (retry) => {
17
+ try {
18
+ await checkServiceAvailable(request.port, applyResult.address, 2000);
19
+ }
20
+ catch (error) {
21
+ console.log("Service is not ready, waiting...");
22
+ retry(error);
23
+ }
24
+ });
14
25
  return {
15
26
  address: applyResult.address,
16
27
  cloudStorage: new AwsS3CloudStorage_1.AwsS3CloudStorage(request.proxyRegion, request.bucket, applyResult.bucketDomain),
@@ -22,4 +33,17 @@ class TerraformTunnelProxyOperations {
22
33
  }
23
34
  }
24
35
  exports.TerraformTunnelProxyOperations = TerraformTunnelProxyOperations;
36
+ async function checkServiceAvailable(port, host, timeout) {
37
+ const socket = net.connect({ port, host, family: 4, timeout });
38
+ try {
39
+ await new Promise((resolve, reject) => {
40
+ socket.once("connect", resolve);
41
+ socket.once("timeout", () => reject("timeout"));
42
+ socket.once("error", (err) => reject(err));
43
+ });
44
+ }
45
+ finally {
46
+ socket.destroy();
47
+ }
48
+ }
25
49
  //# sourceMappingURL=TerraformTunnelProxyOperations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TerraformTunnelProxyOperations.js","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":";;;;AAKA,+DAAyC;AAEzC,2DAAwD;AACxD,qDAA+B;AAE/B,MAAa,8BAA8B;IACzC,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE7D,KAAK,CAAC,MAAM,CAAC,OAAmC;QAC9C,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,KAAK,CACvC,OAAO,EACP,IAAI,CAAC,aAAa,CAAC,kBAAkB,EACrC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CACtC,CAAC;QACF,OAAO;YACL,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,YAAY,EAAE,IAAI,qCAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC;SACnG,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACtG,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;CACF;AAnBD,wEAmBC"}
1
+ {"version":3,"file":"TerraformTunnelProxyOperations.js","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":";;;;AAKA,+DAAyC;AAEzC,2DAAwD;AACxD,qDAA+B;AAC/B,iDAA2B;AAC3B,0EAAyC;AAEzC,MAAa,8BAA8B;IACzC,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE7D,KAAK,CAAC,MAAM,CAAC,OAAmC;QAC9C,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,KAAK,CACvC,OAAO,EACP,IAAI,CAAC,aAAa,CAAC,kBAAkB,EACrC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CACtC,CAAC;QACF,MAAM,uBAAY,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACjC,IAAI;gBACF,MAAM,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;aACtE;YAAC,OAAO,KAAK,EAAE;gBACd,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;gBAChD,KAAK,CAAC,KAAK,CAAC,CAAC;aACd;QACH,CAAC,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,YAAY,EAAE,IAAI,qCAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC;SACnG,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACtG,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;CACF;AA3BD,wEA2BC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAY,EAAE,IAAY,EAAE,OAAe;IAC9E,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/D,IAAI;QACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;KACJ;YAAS;QACR,MAAM,CAAC,OAAO,EAAE,CAAC;KAClB;AACH,CAAC"}
@@ -7,6 +7,8 @@ import * as terraform from "./terraform";
7
7
  import { Configuration } from "./Configuration";
8
8
  import { AwsS3CloudStorage } from "./AwsS3CloudStorage";
9
9
  import * as fs from "fs-extra";
10
+ import * as net from "net";
11
+ import promiseRetry from "promise-retry";
10
12
 
11
13
  export class TerraformTunnelProxyOperations implements TunnelProxyOperations {
12
14
  constructor(private readonly configuration: Configuration) {}
@@ -17,6 +19,14 @@ export class TerraformTunnelProxyOperations implements TunnelProxyOperations {
17
19
  this.configuration.terraformWorkspace,
18
20
  this.configuration.aliyun.credentials
19
21
  );
22
+ await promiseRetry(async (retry) => {
23
+ try {
24
+ await checkServiceAvailable(request.port, applyResult.address, 2000);
25
+ } catch (error) {
26
+ console.log("Service is not ready, waiting...");
27
+ retry(error);
28
+ }
29
+ });
20
30
  return {
21
31
  address: applyResult.address,
22
32
  cloudStorage: new AwsS3CloudStorage(request.proxyRegion, request.bucket, applyResult.bucketDomain),
@@ -28,3 +38,16 @@ export class TerraformTunnelProxyOperations implements TunnelProxyOperations {
28
38
  await fs.rm(this.configuration.terraformWorkspace, { force: true, recursive: true });
29
39
  }
30
40
  }
41
+
42
+ async function checkServiceAvailable(port: number, host: string, timeout: number): Promise<void> {
43
+ const socket = net.connect({ port, host, family: 4, timeout });
44
+ try {
45
+ await new Promise((resolve, reject) => {
46
+ socket.once("connect", resolve);
47
+ socket.once("timeout", () => reject("timeout"));
48
+ socket.once("error", (err) => reject(err));
49
+ });
50
+ } finally {
51
+ socket.destroy();
52
+ }
53
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["terraform.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAmC,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAK7E,wBAAsB,KAAK,CACzB,OAAO,EAAE,0BAA0B,EACnC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAOpD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5F"}
1
+ {"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["terraform.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAmC,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAM7E,wBAAsB,KAAK,CACzB,OAAO,EAAE,0BAA0B,EACnC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAOpD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5F"}
@@ -8,9 +8,10 @@ const util = tslib_1.__importStar(require("util"));
8
8
  const process = tslib_1.__importStar(require("process"));
9
9
  const fs = tslib_1.__importStar(require("fs-extra"));
10
10
  const path = tslib_1.__importStar(require("path"));
11
+ const promise_retry_1 = tslib_1.__importDefault(require("promise-retry"));
11
12
  async function apply(request, workdir, credentials) {
12
13
  await init(request, workdir);
13
- await provisioning(["apply", "-auto-approve"], workdir, aliyunCredentials_1.asTerraformEnvironmentVariables(credentials));
14
+ await provisioningRetry(["apply", "-auto-approve"], workdir, aliyunCredentials_1.asTerraformEnvironmentVariables(credentials));
14
15
  return {
15
16
  address: await inspecting(["output", "-raw", "address"], workdir),
16
17
  bucketDomain: await inspecting(["output", "-raw", "bucket_domain_name"], workdir),
@@ -22,7 +23,7 @@ async function destroy(workdir, credentials) {
22
23
  console.log("Tunnel proxy never created, nothing to destroy");
23
24
  return;
24
25
  }
25
- await provisioning(["destroy", "-auto-approve"], workdir, aliyunCredentials_1.asTerraformEnvironmentVariables(credentials));
26
+ await provisioningRetry(["destroy", "-auto-approve"], workdir, aliyunCredentials_1.asTerraformEnvironmentVariables(credentials));
26
27
  }
27
28
  exports.destroy = destroy;
28
29
  async function init(request, workdir) {
@@ -37,10 +38,20 @@ async function init(request, workdir) {
37
38
  });
38
39
  if (!(await fs.pathExists(path.join(workdir, ".terraform")))) {
39
40
  await fs.copy(path.resolve(__dirname, "..", "..", "terraform"), workdir, { overwrite: true, recursive: true });
40
- await provisioning(["init"], workdir);
41
+ await provisioningRetry(["init"], workdir);
41
42
  }
42
43
  }
43
- async function provisioning(args, cwd, customEnv = {}) {
44
+ async function provisioningRetry(args, cwd, customEnv = {}) {
45
+ await promise_retry_1.default(async (retry) => {
46
+ try {
47
+ await provisioning(args, cwd, customEnv);
48
+ }
49
+ catch (error) {
50
+ retry(error);
51
+ }
52
+ });
53
+ }
54
+ async function provisioning(args, cwd, customEnv) {
44
55
  return new Promise((resolve, reject) => {
45
56
  const p = child_process.spawn("terraform", args, { cwd, stdio: "inherit", env: Object.assign(Object.assign({}, process.env), customEnv) });
46
57
  p.on("close", (code) => {
@@ -1 +1 @@
1
- {"version":3,"file":"terraform.js","sourceRoot":"","sources":["terraform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terraform.js","sourceRoot":"","sources":["terraform.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import { TunnelProxyCreatingRequest } from "../domain/TunnelProxyOperations";
5
5
  import * as process from "process";
6
6
  import * as fs from "fs-extra";
7
7
  import * as path from "path";
8
+ import promiseRetry from "promise-retry";
8
9
 
9
10
  export async function apply(
10
11
  request: TunnelProxyCreatingRequest,
@@ -12,7 +13,7 @@ export async function apply(
12
13
  credentials: AliyunCredentials
13
14
  ): Promise<{ address: string; bucketDomain: string }> {
14
15
  await init(request, workdir);
15
- await provisioning(["apply", "-auto-approve"], workdir, asTerraformEnvironmentVariables(credentials));
16
+ await provisioningRetry(["apply", "-auto-approve"], workdir, asTerraformEnvironmentVariables(credentials));
16
17
  return {
17
18
  address: await inspecting(["output", "-raw", "address"], workdir),
18
19
  bucketDomain: await inspecting(["output", "-raw", "bucket_domain_name"], workdir),
@@ -24,7 +25,7 @@ export async function destroy(workdir: string, credentials: AliyunCredentials):
24
25
  console.log("Tunnel proxy never created, nothing to destroy");
25
26
  return;
26
27
  }
27
- await provisioning(["destroy", "-auto-approve"], workdir, asTerraformEnvironmentVariables(credentials));
28
+ await provisioningRetry(["destroy", "-auto-approve"], workdir, asTerraformEnvironmentVariables(credentials));
28
29
  }
29
30
 
30
31
  async function init(request: TunnelProxyCreatingRequest, workdir: string): Promise<void> {
@@ -39,11 +40,21 @@ async function init(request: TunnelProxyCreatingRequest, workdir: string): Promi
39
40
  });
40
41
  if (!(await fs.pathExists(path.join(workdir, ".terraform")))) {
41
42
  await fs.copy(path.resolve(__dirname, "..", "..", "terraform"), workdir, { overwrite: true, recursive: true });
42
- await provisioning(["init"], workdir);
43
+ await provisioningRetry(["init"], workdir);
43
44
  }
44
45
  }
45
46
 
46
- async function provisioning(args: string[], cwd: string, customEnv: Record<string, string> = {}): Promise<void> {
47
+ async function provisioningRetry(args: string[], cwd: string, customEnv: Record<string, string> = {}): Promise<void> {
48
+ await promiseRetry(async (retry) => {
49
+ try {
50
+ await provisioning(args, cwd, customEnv);
51
+ } catch (error) {
52
+ retry(error);
53
+ }
54
+ });
55
+ }
56
+
57
+ async function provisioning(args: string[], cwd: string, customEnv: Record<string, string>): Promise<void> {
47
58
  return new Promise<void>((resolve, reject) => {
48
59
  const p = child_process.spawn("terraform", args, { cwd, stdio: "inherit", env: { ...process.env, ...customEnv } });
49
60
  p.on("close", (code) => {
@@ -1 +1 @@
1
- {"version":3,"file":"Clash.d.ts","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,oBAAY,yBAAyB,GAAG,YAAY,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,yBAAyB,GAAG,MAAM,CAgB/E"}
1
+ {"version":3,"file":"Clash.d.ts","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,oBAAY,yBAAyB,GAAG,YAAY,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,yBAAyB,GAAG,MAAM,CA0B/E"}
@@ -7,10 +7,19 @@ function generateConfigFrom(endpoints) {
7
7
  return yaml_1.default.stringify({
8
8
  port: 7890,
9
9
  "socks-port": 7891,
10
- mode: "global",
10
+ "redir-port": 7892,
11
+ "tproxy-port": 7893,
12
+ "mixed-port": 7890,
13
+ mode: "rule",
14
+ dns: {
15
+ enable: true,
16
+ listen: "0.0.0.0:53",
17
+ "enhanced-mode": "redir-host",
18
+ nameserver: ["223.5.5.5", "119.29.29.29", "114.114.114.114", "tls://dns.rubyfish.cn:853"],
19
+ },
11
20
  proxies: [
12
21
  {
13
- name: "shadowsocks",
22
+ name: "auto",
14
23
  type: "ss",
15
24
  server: endpoints.address,
16
25
  port: endpoints.port,
@@ -18,6 +27,7 @@ function generateConfigFrom(endpoints) {
18
27
  password: endpoints.password,
19
28
  },
20
29
  ],
30
+ rules: ["DOMAIN-SUFFIX,google.com,auto", "DOMAIN,ad.com,REJECT", "GEOIP,CN,DIRECT", "MATCH,auto"],
21
31
  });
22
32
  }
23
33
  exports.generateConfigFrom = generateConfigFrom;
@@ -1 +1 @@
1
- {"version":3,"file":"Clash.js","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":";;;;AAAA,wDAAwB;AAOxB,SAAgB,kBAAkB,CAAC,SAAoC;IACrE,OAAO,cAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,IAAI;QACV,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,SAAS,CAAC,OAAO;gBACzB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,MAAM,EAAE,SAAS,CAAC,mBAAmB;gBACrC,QAAQ,EAAE,SAAS,CAAC,QAAQ;aAC7B;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAhBD,gDAgBC"}
1
+ {"version":3,"file":"Clash.js","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":";;;;AAAA,wDAAwB;AAOxB,SAAgB,kBAAkB,CAAC,SAAoC;IACrE,OAAO,cAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,IAAI;QACV,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,IAAI;QACnB,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,YAAY;YACpB,eAAe,EAAE,YAAY;YAC7B,UAAU,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,2BAA2B,CAAC;SAC1F;QACD,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,SAAS,CAAC,OAAO;gBACzB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,MAAM,EAAE,SAAS,CAAC,mBAAmB;gBACrC,QAAQ,EAAE,SAAS,CAAC,QAAQ;aAC7B;SACF;QACD,KAAK,EAAE,CAAC,+BAA+B,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,YAAY,CAAC;KAClG,CAAC,CAAC;AACL,CAAC;AA1BD,gDA0BC"}
@@ -9,10 +9,19 @@ export function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string
9
9
  return yaml.stringify({
10
10
  port: 7890,
11
11
  "socks-port": 7891,
12
- mode: "global",
12
+ "redir-port": 7892,
13
+ "tproxy-port": 7893,
14
+ "mixed-port": 7890,
15
+ mode: "rule",
16
+ dns: {
17
+ enable: true,
18
+ listen: "0.0.0.0:53",
19
+ "enhanced-mode": "redir-host",
20
+ nameserver: ["223.5.5.5", "119.29.29.29", "114.114.114.114", "tls://dns.rubyfish.cn:853"],
21
+ },
13
22
  proxies: [
14
23
  {
15
- name: "shadowsocks",
24
+ name: "auto",
16
25
  type: "ss",
17
26
  server: endpoints.address,
18
27
  port: endpoints.port,
@@ -20,5 +29,6 @@ export function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string
20
29
  password: endpoints.password,
21
30
  },
22
31
  ],
32
+ rules: ["DOMAIN-SUFFIX,google.com,auto", "DOMAIN,ad.com,REJECT", "GEOIP,CN,DIRECT", "MATCH,auto"],
23
33
  });
24
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fanqiang",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Tunnel Proxy Auto Deployment",
5
5
  "bin": "./bin/fanqiang.js",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  "files": [
24
24
  "/bin",
25
25
  "/lib",
26
- "/cloud-init",
26
+ "/terraform",
27
27
  "index.*"
28
28
  ],
29
29
  "homepage": "https://github.com/zhifanz/fanqiang#readme",
@@ -32,14 +32,11 @@
32
32
  "@commitlint/config-conventional": "^12.1.4",
33
33
  "@semantic-release/changelog": "^5.0.1",
34
34
  "@semantic-release/git": "^9.0.0",
35
- "@types/ali-oss": "^6.0.10",
36
35
  "@types/fs-extra": "^9.0.12",
37
36
  "@types/lodash": "^4.14.171",
38
37
  "@types/mocha": "^8.2.3",
39
- "@types/netmask": "^1.0.30",
40
38
  "@types/node": "^14.14.31",
41
- "@types/qs": "^6.9.7",
42
- "@types/tmp": "^0.2.1",
39
+ "@types/promise-retry": "^1.1.3",
43
40
  "@types/yargs": "^17.0.2",
44
41
  "@typescript-eslint/eslint-plugin": "^4.28.2",
45
42
  "@typescript-eslint/parser": "^4.28.2",
@@ -62,18 +59,12 @@
62
59
  },
63
60
  "dependencies": {
64
61
  "@alicloud/credentials": "^2.1.1",
65
- "@alicloud/openapi-client": "^0.3.3",
66
- "@alicloud/tea-typescript": "^1.7.1",
67
- "@aws-sdk/client-iam": "^3.27.0",
68
- "@aws-sdk/client-lightsail": "^3.21.0",
69
62
  "@aws-sdk/client-s3": "^3.27.0",
70
- "ali-oss": "^6.16.0",
63
+ "@aws-sdk/node-config-provider": "^3.29.0",
71
64
  "dotenv": "^10.0.0",
72
65
  "fs-extra": "^10.0.0",
73
66
  "lodash": "^4.17.21",
74
- "netmask": "^2.0.2",
75
- "qs": "^6.10.1",
76
- "tmp": "^0.2.1",
67
+ "promise-retry": "^2.0.1",
77
68
  "tslib": "^2.3.0",
78
69
  "yaml": "^1.10.2",
79
70
  "yargs": "^17.0.1"
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ PORT=${port}
3
+ ENCRYPTION_ALGORITHM=${encryption_algorithm}
4
+ PASSWORD=${password}
5
+
6
+ curl --location -o /tmp/shadowsocks.tar.xz https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.11.1/shadowsocks-v1.11.1.x86_64-unknown-linux-gnu.tar.xz
7
+ mkdir /var/lib/shadowsocks
8
+ tar -x -f /tmp/shadowsocks.tar.xz -C /var/lib/shadowsocks
9
+ /var/lib/shadowsocks/ssserver -s "[::]:$PORT" -m "$ENCRYPTION_ALGORITHM" -k "$PASSWORD" -d
@@ -0,0 +1,38 @@
1
+ #!/bin/bash
2
+
3
+ PROXY_ADDRESS=${proxy_address}
4
+ PROXY_PORT=${proxy_port}
5
+ ELASTIC_IP_ALLOCATION_ID=${elastic_ip_allocation_id}
6
+ REGION=${region}
7
+ RAM_ROLE_NAME=${ram_role_name}
8
+
9
+ aliyun configure set --region $REGION --mode EcsRamRole --ram-role-name $RAM_ROLE_NAME
10
+ aliyun --endpoint "vpc-vpc.$REGION.aliyuncs.com" vpc UnassociateEipAddress --AllocationId $ELASTIC_IP_ALLOCATION_ID || true
11
+ aliyun --endpoint "vpc-vpc.$REGION.aliyuncs.com" vpc AssociateEipAddress --AllocationId $ELASTIC_IP_ALLOCATION_ID --InstanceId "i-$${HOSTNAME: 2: 20}"
12
+ sleep 5
13
+
14
+ yum install nginx -y &>> ~/cloud-init.log
15
+ sleep 5
16
+ yum install nginx-all-modules -y &>> ~/cloud-init.log
17
+
18
+ cat > /etc/nginx/nginx.conf <<EOF
19
+ user nginx;
20
+ worker_processes auto;
21
+ error_log /var/log/nginx/error.log;
22
+ pid /run/nginx.pid;
23
+
24
+ include /usr/share/nginx/modules/*.conf;
25
+
26
+ events {
27
+ worker_connections 1024;
28
+ }
29
+
30
+ stream {
31
+ server {
32
+ listen $PROXY_PORT;
33
+ proxy_pass $PROXY_ADDRESS:$PROXY_PORT;
34
+ }
35
+ }
36
+ EOF
37
+
38
+ systemctl start nginx
@@ -0,0 +1,25 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "hashicorp/aws"
5
+ version = "~> 3.0"
6
+ }
7
+ alicloud = {
8
+ source = "aliyun/alicloud"
9
+ version = "1.134.0"
10
+ }
11
+ }
12
+ }
13
+ provider "aws" {
14
+ region = var.proxy_region
15
+ }
16
+ provider "alicloud" {
17
+ region = var.tunnel_region
18
+ }
19
+
20
+ locals {
21
+ instance_type = "ecs.t5-lc2m1.nano"
22
+ image_id = "aliyun_2_1903_x64_20G_alibase_20210726.vhd"
23
+ internet_max_bandwidth_out = 100
24
+ max_price_per_hour = "0.05"
25
+ }
@@ -0,0 +1,6 @@
1
+ output "address" {
2
+ value = alicloud_eip_address.default.ip_address
3
+ }
4
+ output "bucket_domain_name" {
5
+ value = aws_s3_bucket.default.bucket_domain_name
6
+ }
@@ -0,0 +1,34 @@
1
+ resource "aws_lightsail_instance" "default" {
2
+ availability_zone = data.aws_availability_zones.default.names[0]
3
+ blueprint_id = "centos_8"
4
+ bundle_id = "nano_2_0"
5
+ name = "fanqiang"
6
+ user_data = templatefile("${path.root}/cloud-init/proxy-init.sh", {
7
+ port = var.port,
8
+ encryption_algorithm = var.encryption_algorithm,
9
+ password = var.password
10
+ })
11
+ }
12
+
13
+ resource "aws_lightsail_instance_public_ports" "default" {
14
+ instance_name = aws_lightsail_instance.default.name
15
+
16
+ dynamic "port_info" {
17
+ for_each = [var.port, 22]
18
+ content {
19
+ protocol = "tcp"
20
+ from_port = port_info.value
21
+ to_port = port_info.value
22
+ }
23
+ }
24
+ }
25
+
26
+ resource "aws_s3_bucket" "default" {
27
+ bucket = var.bucket
28
+ acl = "public-read"
29
+ force_destroy = true
30
+ }
31
+
32
+ data "aws_availability_zones" "default" {
33
+ state = "available"
34
+ }
@@ -0,0 +1,106 @@
1
+ resource "alicloud_vpc" "default" {
2
+ cidr_block = "192.168.0.0/16"
3
+ }
4
+
5
+ resource "alicloud_vswitch" "default" {
6
+ count = length(data.alicloud_zones.default.ids)
7
+ zone_id = data.alicloud_zones.default.ids[count.index]
8
+ cidr_block = "192.168.${count.index}.0/24"
9
+ vpc_id = alicloud_vpc.default.id
10
+ }
11
+
12
+ resource "alicloud_security_group" "default" {
13
+ vpc_id = alicloud_vpc.default.id
14
+ }
15
+
16
+ resource "alicloud_security_group_rule" "default" {
17
+ for_each = toset([tostring(var.port), "22"])
18
+ security_group_id = alicloud_security_group.default.id
19
+ ip_protocol = "tcp"
20
+ type = "ingress"
21
+ cidr_ip = "0.0.0.0/0"
22
+ port_range = "${each.key}/${each.key}"
23
+ }
24
+
25
+ resource "alicloud_auto_provisioning_group" "default" {
26
+ launch_template_id = alicloud_ecs_launch_template.default.id
27
+ total_target_capacity = "1"
28
+ pay_as_you_go_target_capacity = "0"
29
+ spot_target_capacity = "1"
30
+ auto_provisioning_group_type = "maintain"
31
+ spot_allocation_strategy = "lowest-price"
32
+ spot_instance_interruption_behavior = "terminate"
33
+ excess_capacity_termination_policy = "termination"
34
+ terminate_instances = true
35
+ dynamic "launch_template_config" {
36
+ for_each = alicloud_vswitch.default.*.id
37
+ content {
38
+ instance_type = local.instance_type
39
+ max_price = local.max_price_per_hour
40
+ vswitch_id = launch_template_config.value
41
+ weighted_capacity = "1"
42
+ }
43
+ }
44
+ }
45
+
46
+ resource "alicloud_ecs_launch_template" "default" {
47
+ launch_template_name = "fanqiang"
48
+ image_id = local.image_id
49
+ instance_charge_type = "PostPaid"
50
+ instance_type = local.instance_type
51
+ security_group_id = alicloud_security_group.default.id
52
+ key_pair_name = length(data.alicloud_ecs_key_pairs.default) > 0 ? data.alicloud_ecs_key_pairs.default.names[0] : null
53
+ spot_duration = 0
54
+ spot_strategy = "SpotAsPriceGo"
55
+ ram_role_name = alicloud_ram_role.default.id
56
+ user_data = base64encode(templatefile("${path.root}/cloud-init/tunnel-init.sh", {
57
+ proxy_port = var.port,
58
+ proxy_address = aws_lightsail_instance.default.public_ip_address,
59
+ elastic_ip_allocation_id = alicloud_eip_address.default.id,
60
+ region = var.tunnel_region
61
+ ram_role_name = alicloud_ram_role.default.id
62
+ }))
63
+ system_disk {
64
+ category = "cloud_efficiency"
65
+ delete_with_instance = true
66
+ size = 40
67
+ }
68
+ }
69
+
70
+ data "alicloud_ecs_key_pairs" "default" {}
71
+
72
+ resource "alicloud_ram_role" "default" {
73
+ name = "FangqiangEcsEipAccessRole"
74
+ document = <<EOF
75
+ {
76
+ "Statement": [
77
+ {
78
+ "Action": "sts:AssumeRole",
79
+ "Effect": "Allow",
80
+ "Principal": {
81
+ "Service": [
82
+ "ecs.aliyuncs.com"
83
+ ]
84
+ }
85
+ }
86
+ ],
87
+ "Version": "1"
88
+ }
89
+ EOF
90
+ force = true
91
+ }
92
+
93
+ resource "alicloud_ram_role_policy_attachment" "default" {
94
+ policy_name = "AliyunEIPFullAccess"
95
+ policy_type = "System"
96
+ role_name = alicloud_ram_role.default.id
97
+ }
98
+
99
+ resource "alicloud_eip_address" "default" {
100
+ bandwidth = local.internet_max_bandwidth_out
101
+ internet_charge_type = "PayByTraffic"
102
+ }
103
+
104
+ data "alicloud_zones" "default" {}
105
+
106
+
@@ -0,0 +1,18 @@
1
+ variable "proxy_region" {
2
+ type = string
3
+ }
4
+ variable "tunnel_region" {
5
+ type = string
6
+ }
7
+ variable "port" {
8
+ type = number
9
+ }
10
+ variable "password" {
11
+ type = string
12
+ }
13
+ variable "encryption_algorithm" {
14
+ type = string
15
+ }
16
+ variable "bucket" {
17
+ type = string
18
+ }